diff --git a/.dependabot/dependabot.yaml b/.dependabot/dependabot.yaml new file mode 100644 index 00000000..d5137800 --- /dev/null +++ b/.dependabot/dependabot.yaml @@ -0,0 +1,16 @@ +version: 2 +updates: +- package-ecosystem: nuget + directory: "/" + schedule: + interval: daily + time: "06:00" + timezone: America/Vancouver + open-pull-requests-limit: 10 + ignore: + - dependency-name: Microsoft.AspNetCore.* + versions: + - 5.x + - dependency-name: System.Net.Http.Json + versions: + - 5.x diff --git a/BlazorTable.sln b/BlazorTable.sln index 5c57f951..04dd9e0c 100644 --- a/BlazorTable.sln +++ b/BlazorTable.sln @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .github\workflows\build.yml = .github\workflows\build.yml .github\workflows\cicd.yml = .github\workflows\cicd.yml + .dependabot\dependabot.yaml = .dependabot\dependabot.yaml README.md = README.md .github\workflows\release.yml = .github\workflows\release.yml EndProjectSection diff --git a/README.md b/README.md index ea881b37..d0a00b53 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,8 @@ Blazor Table Component with Sorting, Paging and Filtering - dotnet add package BlazorTable - Add to the index.html or _Hosts.cshtml - `` +- Add call to Program.cs or Startup.cs + - Services.AddBlazorTable(); ## Features - Column Reordering diff --git a/src/BlazorTable.Sample.Server/Startup.cs b/src/BlazorTable.Sample.Server/Startup.cs index d8e1a10b..aba6addb 100644 --- a/src/BlazorTable.Sample.Server/Startup.cs +++ b/src/BlazorTable.Sample.Server/Startup.cs @@ -42,6 +42,7 @@ public void ConfigureServices(IServiceCollection services) }; }); } + services.AddBlazorTable(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. diff --git a/src/BlazorTable.Sample.Shared/BlazorTable.Sample.Shared.csproj b/src/BlazorTable.Sample.Shared/BlazorTable.Sample.Shared.csproj index 06c19390..5154481d 100644 --- a/src/BlazorTable.Sample.Shared/BlazorTable.Sample.Shared.csproj +++ b/src/BlazorTable.Sample.Shared/BlazorTable.Sample.Shared.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/src/BlazorTable.Sample.Shared/NavMenu.razor b/src/BlazorTable.Sample.Shared/NavMenu.razor index 11e34bfc..2a81e847 100644 --- a/src/BlazorTable.Sample.Shared/NavMenu.razor +++ b/src/BlazorTable.Sample.Shared/NavMenu.razor @@ -67,6 +67,11 @@ Dynamic Columns + diff --git a/src/BlazorTable.Sample.Shared/Pages/ToggleColumnVisibility.razor b/src/BlazorTable.Sample.Shared/Pages/ToggleColumnVisibility.razor new file mode 100644 index 00000000..3d7bf8ff --- /dev/null +++ b/src/BlazorTable.Sample.Shared/Pages/ToggleColumnVisibility.razor @@ -0,0 +1,69 @@ +@page "/ToggleColumnVisibility" +@inject HttpClient Http +@using BlazorTable +@using System.ComponentModel + +

Toggle Column Visibility

+ + + + + + + + + + + + + + + + + + + + +
+ +@code +{ + [Inject] + private HttpClient httpClient { get; set; } + + private PersonData[] data; + + private bool showSearchBar; + + protected override async Task OnInitializedAsync() + { + data = await httpClient.GetFromJsonAsync("sample-data/MOCK_DATA.json"); + } + + public class PersonData + { + public int? id { get; set; } + public string full_name { get; set; } + public string email { get; set; } + public bool? paid { get; set; } + public decimal? price { get; set; } + public CreditCard? cc_type { get; set; } + public DateTime? created_date { get; set; } + } + + public enum CreditCard + { + none = 0, + [Description("MasterCard")] + MasterCard = 1, + Visa = 2 + } +} diff --git a/src/BlazorTable.Sample.Wasm/Program.cs b/src/BlazorTable.Sample.Wasm/Program.cs index 2d10099a..a4cc9539 100644 --- a/src/BlazorTable.Sample.Wasm/Program.cs +++ b/src/BlazorTable.Sample.Wasm/Program.cs @@ -16,6 +16,7 @@ public static async Task Main(string[] args) builder.RootComponents.Add("app"); builder.Services.AddSingleton(new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); + builder.Services.AddBlazorTable(); await builder.Build().RunAsync(); } diff --git a/src/BlazorTable.Tests/BlazorTable.Tests.csproj b/src/BlazorTable.Tests/BlazorTable.Tests.csproj index 450b1c47..e8ae8d44 100644 --- a/src/BlazorTable.Tests/BlazorTable.Tests.csproj +++ b/src/BlazorTable.Tests/BlazorTable.Tests.csproj @@ -7,10 +7,10 @@ - + - + all diff --git a/src/BlazorTable/BlazorTable.csproj b/src/BlazorTable/BlazorTable.csproj index 08c8f841..6600f78c 100644 --- a/src/BlazorTable/BlazorTable.csproj +++ b/src/BlazorTable/BlazorTable.csproj @@ -27,10 +27,11 @@ - - - - + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -42,5 +43,20 @@ + + + + True + True + Localization.resx + + + + + + ResXFileCodeGenerator + Localization.Designer.cs + + \ No newline at end of file diff --git a/src/BlazorTable/Components/Column.razor.cs b/src/BlazorTable/Components/Column.razor.cs index 847bc112..bd0257f6 100644 --- a/src/BlazorTable/Components/Column.razor.cs +++ b/src/BlazorTable/Components/Column.razor.cs @@ -48,6 +48,12 @@ public string Title [Parameter] public bool Filterable { get; set; } + /// + /// Column can be hidden + /// + [Parameter] + public bool Hideable { get; set; } + /// /// Normal Item Template /// @@ -142,6 +148,22 @@ public string Title /// public bool FilterOpen { get; private set; } + private bool _visible = true; + + /// + /// Column visibility + /// True if current column is visible else false. + /// + public bool Visible + { + get { return _visible; } + set + { + _visible = value; + Table.Refresh(); + } + } + /// /// Column Data Type /// diff --git a/src/BlazorTable/Components/FilterManager.razor b/src/BlazorTable/Components/FilterManager.razor index 5e161d5b..a698ca80 100644 --- a/src/BlazorTable/Components/FilterManager.razor +++ b/src/BlazorTable/Components/FilterManager.razor @@ -1,5 +1,6 @@ @namespace BlazorTable @typeparam TableItem +@inject Microsoft.Extensions.Localization.IStringLocalizer Localization @ChildContent @@ -7,7 +8,7 @@
- - - + + +
diff --git a/src/BlazorTable/Components/Localization.Designer.cs b/src/BlazorTable/Components/Localization.Designer.cs new file mode 100644 index 00000000..3e1961dc --- /dev/null +++ b/src/BlazorTable/Components/Localization.Designer.cs @@ -0,0 +1,405 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BlazorTable.Components { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Localization { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Localization() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BlazorTable.Components.Localization", typeof(Localization).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to False. + /// + internal static string BooleanConditionFalse { + get { + return ResourceManager.GetString("BooleanConditionFalse", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not null. + /// + internal static string BooleanConditionIsNotNull { + get { + return ResourceManager.GetString("BooleanConditionIsNotNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is null. + /// + internal static string BooleanConditionIsNull { + get { + return ResourceManager.GetString("BooleanConditionIsNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to True. + /// + internal static string BooleanConditionTrue { + get { + return ResourceManager.GetString("BooleanConditionTrue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is equal to. + /// + internal static string CustomSelectConditionIsEqualTo { + get { + return ResourceManager.GetString("CustomSelectConditionIsEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not equal to. + /// + internal static string CustomSelectConditionIsNotEqualTo { + get { + return ResourceManager.GetString("CustomSelectConditionIsNotEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not null. + /// + internal static string CustomSelectConditionIsNotNull { + get { + return ResourceManager.GetString("CustomSelectConditionIsNotNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is null. + /// + internal static string CustomSelectConditionIsNull { + get { + return ResourceManager.GetString("CustomSelectConditionIsNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is equal to. + /// + internal static string EnumConditionIsEqualTo { + get { + return ResourceManager.GetString("EnumConditionIsEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not equal to. + /// + internal static string EnumConditionIsNotEqualTo { + get { + return ResourceManager.GetString("EnumConditionIsNotEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not null. + /// + internal static string EnumConditionIsNotNull { + get { + return ResourceManager.GetString("EnumConditionIsNotNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is null. + /// + internal static string EnumConditionIsNull { + get { + return ResourceManager.GetString("EnumConditionIsNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Apply. + /// + internal static string FilterManagerApply { + get { + return ResourceManager.GetString("FilterManagerApply", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Clear. + /// + internal static string FilterManagerClear { + get { + return ResourceManager.GetString("FilterManagerClear", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Close. + /// + internal static string FilterManagerClose { + get { + return ResourceManager.GetString("FilterManagerClose", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is equal to. + /// + internal static string NumberConditionIsEqualTo { + get { + return ResourceManager.GetString("NumberConditionIsEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is greater than. + /// + internal static string NumberConditionIsGreaterThan { + get { + return ResourceManager.GetString("NumberConditionIsGreaterThan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is greater than or equal to. + /// + internal static string NumberConditionIsGreaterThanOrEqualTo { + get { + return ResourceManager.GetString("NumberConditionIsGreaterThanOrEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is less than. + /// + internal static string NumberConditionIsLessThan { + get { + return ResourceManager.GetString("NumberConditionIsLessThan", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is less than or equal to. + /// + internal static string NumberConditionIsLessThanOrEqualTo { + get { + return ResourceManager.GetString("NumberConditionIsLessThanOrEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not equal to. + /// + internal static string NumberConditionIsnotEqualTo { + get { + return ResourceManager.GetString("NumberConditionIsnotEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not null. + /// + internal static string NumberConditionIsNotNull { + get { + return ResourceManager.GetString("NumberConditionIsNotNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is null. + /// + internal static string NumberConditionIsNull { + get { + return ResourceManager.GetString("NumberConditionIsNull", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to First. + /// + internal static string PagerFirst { + get { + return ResourceManager.GetString("PagerFirst", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Last. + /// + internal static string PagerLast { + get { + return ResourceManager.GetString("PagerLast", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Next. + /// + internal static string PagerNext { + get { + return ResourceManager.GetString("PagerNext", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Previous. + /// + internal static string PagerPrevious { + get { + return ResourceManager.GetString("PagerPrevious", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Contains. + /// + internal static string StringConditionContains { + get { + return ResourceManager.GetString("StringConditionContains", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Does not contain. + /// + internal static string StringConditionDoesNotContain { + get { + return ResourceManager.GetString("StringConditionDoesNotContain", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ends with. + /// + internal static string StringConditionEndsWith { + get { + return ResourceManager.GetString("StringConditionEndsWith", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is equal to. + /// + internal static string StringConditionIsEqualTo { + get { + return ResourceManager.GetString("StringConditionIsEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not equal to. + /// + internal static string StringConditionIsNotEqualTo { + get { + return ResourceManager.GetString("StringConditionIsNotEqualTo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is not null or empty. + /// + internal static string StringConditionIsNotNullOrEmpty { + get { + return ResourceManager.GetString("StringConditionIsNotNullOrEmpty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Is null or empty. + /// + internal static string StringConditionIsNullOrEmpty { + get { + return ResourceManager.GetString("StringConditionIsNullOrEmpty", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Starts with. + /// + internal static string StringConditionStartsWith { + get { + return ResourceManager.GetString("StringConditionStartsWith", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Details View. + /// + internal static string TableDetailsView { + get { + return ResourceManager.GetString("TableDetailsView", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Global Search.... + /// + internal static string TableGlobalSearch { + get { + return ResourceManager.GetString("TableGlobalSearch", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Loading.... + /// + internal static string TableLoading { + get { + return ResourceManager.GetString("TableLoading", resourceCulture); + } + } + } +} diff --git a/src/BlazorTable/Components/Localization.de.resx b/src/BlazorTable/Components/Localization.de.resx new file mode 100644 index 00000000..05448a3d --- /dev/null +++ b/src/BlazorTable/Components/Localization.de.resx @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Falsch + + + Ist nicht null + + + Ist null + + + Wahr + + + Ist gleich + + + Ist ungleich + + + Ist nicht null + + + Ist null + + + Ist gleich + + + Ist ungleich + + + Ist nicht null + + + Ist null + + + Anwenden + + + Löschen + + + Schließen + + + Ist gleich + + + Ist größer als + + + Ist größer oder gleich als + + + Ist kleiner als + + + Ist kleiner oder gleich als + + + Ist ungleich + + + Ist nicht null + + + Ist null + + + Beginn + + + Ende + + + Nächste + + + Zurück + + + Beinhaltet + + + Beinhaltet nicht + + + Endet mit + + + Ist gleich + + + Ist ungleich + + + Ist nicht Null oder leer + + + Ist Null oder leer + + + Beginnt mit + + + Detailansicht + + + Globale Suche... + + + Lade... + + \ No newline at end of file diff --git a/src/BlazorTable/Components/Localization.resx b/src/BlazorTable/Components/Localization.resx new file mode 100644 index 00000000..8c94477f --- /dev/null +++ b/src/BlazorTable/Components/Localization.resx @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + False + + + Is not null + + + Is null + + + True + + + Is equal to + + + Is not equal to + + + Is not null + + + Is null + + + Is equal to + + + Is not equal to + + + Is not null + + + Is null + + + Apply + + + Clear + + + Close + + + Is equal to + + + Is greater than + + + Is greater than or equal to + + + Is less than + + + Is less than or equal to + + + Is not equal to + + + Is not null + + + Is null + + + First + + + Last + + + Next + + + Previous + + + Contains + + + Does not contain + + + Ends with + + + Is equal to + + + Is not equal to + + + Is not null or empty + + + Is null or empty + + + Starts with + + + Details View + + + Global Search... + + + Loading... + + \ No newline at end of file diff --git a/src/BlazorTable/Components/Pager.razor b/src/BlazorTable/Components/Pager.razor index db0b9b47..6947d9b7 100644 --- a/src/BlazorTable/Components/Pager.razor +++ b/src/BlazorTable/Components/Pager.razor @@ -1,4 +1,5 @@ @namespace BlazorTable +@inject Microsoft.Extensions.Localization.IStringLocalizer Localization @if (AlwaysShow || (Table.TotalPages > 1)) { @@ -34,17 +35,17 @@ } -
  • - First +
  • + @Localization["PagerFirst"]
  • -
  • - Previous +
  • + @Localization["PagerPrevious"]
  • -
  • - Next +
  • + @Localization["PagerNext"]
  • -
  • - Last +
  • + @Localization["PagerLast"]
  • diff --git a/src/BlazorTable/Components/Table.razor b/src/BlazorTable/Components/Table.razor index a8d81b0f..91a4fcbe 100644 --- a/src/BlazorTable/Components/Table.razor +++ b/src/BlazorTable/Components/Table.razor @@ -1,7 +1,6 @@ @namespace BlazorTable @typeparam TableItem - - +@inject Microsoft.Extensions.Localization.IStringLocalizer Localization @if (Columns.Any()) { @@ -9,11 +8,53 @@
    - @if (ShowSearchBar) + @if (ShowSearchBar || Columns.Exists(column => !column.Visible)) { - + } @@ -26,56 +67,68 @@ } @foreach (IColumn column in Columns) { - + + } + + + } } @@ -97,7 +150,7 @@ @if (_detailTemplate != null) { + @if (column.Visible) + { + + } } @@ -155,7 +211,7 @@ else {
    - Loading... + @Localization["TableLoading"]
    } diff --git a/src/BlazorTable/Components/Table.razor.cs b/src/BlazorTable/Components/Table.razor.cs index 824518c3..59470ee3 100644 --- a/src/BlazorTable/Components/Table.razor.cs +++ b/src/BlazorTable/Components/Table.razor.cs @@ -81,6 +81,16 @@ public partial class Table : ITable [Inject] private ILogger> Logger { get; set; } + /// + /// Ref to visibility menu icon for popover display + /// + private ElementReference VisibilityMenuIconRef { get; set; } + + /// + /// True if visibility menu is open otherwise false + /// + private bool VisibilityMenuOpen { get; set; } + /// /// Collection of filtered items /// diff --git a/src/BlazorTable/Filters/BooleanFilter.razor.cs b/src/BlazorTable/Filters/BooleanFilter.razor.cs index d72cb49b..f8526472 100644 --- a/src/BlazorTable/Filters/BooleanFilter.razor.cs +++ b/src/BlazorTable/Filters/BooleanFilter.razor.cs @@ -1,7 +1,7 @@ -using Microsoft.AspNetCore.Components; +using BlazorTable.Components; +using Microsoft.AspNetCore.Components; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Linq.Expressions; namespace BlazorTable @@ -92,16 +92,16 @@ public Expression> GetFilter() public enum BooleanCondition { - [Description("True")] + [LocalizedDescription("BooleanConditionTrue", typeof(Localization))] True, - [Description("False")] + [LocalizedDescription("BooleanConditionFalse", typeof(Localization))] False, - [Description("Is null")] + [LocalizedDescription("BooleanConditionIsNull", typeof(Localization))] IsNull, - [Description("Is not null")] + [LocalizedDescription("BooleanConditionIsNotNull", typeof(Localization))] IsNotNull } } diff --git a/src/BlazorTable/Filters/CustomSelect.razor.cs b/src/BlazorTable/Filters/CustomSelect.razor.cs index 3e3f7928..c8d467b1 100644 --- a/src/BlazorTable/Filters/CustomSelect.razor.cs +++ b/src/BlazorTable/Filters/CustomSelect.razor.cs @@ -1,7 +1,7 @@ -using Microsoft.AspNetCore.Components; +using BlazorTable.Components; +using Microsoft.AspNetCore.Components; using System; using System.Collections.Generic; -using System.ComponentModel; using System.Globalization; using System.Linq; using System.Linq.Expressions; @@ -97,16 +97,16 @@ public void AddSelect(string key, object value) public enum CustomSelectCondition { - [Description("Is equal to")] + [LocalizedDescription("CustomSelectConditionIsEqualTo", typeof(Localization))] IsEqualTo, - [Description("Is not equal to")] + [LocalizedDescription("CustomSelectConditionIsNotEqualTo", typeof(Localization))] IsNotEqualTo, - [Description("Is null")] + [LocalizedDescription("CustomSelectConditionIsNull", typeof(Localization))] IsNull, - [Description("Is not null")] + [LocalizedDescription("CustomSelectConditionIsNotNull", typeof(Localization))] IsNotNull } } diff --git a/src/BlazorTable/Filters/EnumFilter.razor.cs b/src/BlazorTable/Filters/EnumFilter.razor.cs index 04ca4e28..fc29d3ca 100644 --- a/src/BlazorTable/Filters/EnumFilter.razor.cs +++ b/src/BlazorTable/Filters/EnumFilter.razor.cs @@ -1,6 +1,6 @@ -using Microsoft.AspNetCore.Components; +using BlazorTable.Components; +using Microsoft.AspNetCore.Components; using System; -using System.ComponentModel; using System.Globalization; using System.Linq.Expressions; @@ -11,6 +11,9 @@ public partial class EnumFilter : IFilter [CascadingParameter(Name = "Column")] public IColumn Column { get; set; } + [Inject] + Microsoft.Extensions.Localization.IStringLocalizer Localization { get; set; } + private EnumCondition Condition { get; set; } private object FilterValue { get; set; } @@ -87,16 +90,16 @@ public Expression> GetFilter() public enum EnumCondition { - [Description("Is equal to")] + [LocalizedDescription("EnumConditionIsEqualTo", typeof(Localization))] IsEqualTo, - [Description("Is not equal to")] + [LocalizedDescription("EnumConditionIsNotEqualTo", typeof(Localization))] IsNotEqualTo, - [Description("Is null")] + [LocalizedDescription("EnumConditionIsNull", typeof(Localization))] IsNull, - [Description("Is not null")] + [LocalizedDescription("EnumConditionIsNotNull", typeof(Localization))] IsNotNull } } diff --git a/src/BlazorTable/Filters/NumberFilter.razor.cs b/src/BlazorTable/Filters/NumberFilter.razor.cs index 23a3fca3..886ed64b 100644 --- a/src/BlazorTable/Filters/NumberFilter.razor.cs +++ b/src/BlazorTable/Filters/NumberFilter.razor.cs @@ -1,7 +1,6 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Logging; +using BlazorTable.Components; +using Microsoft.AspNetCore.Components; using System; -using System.ComponentModel; using System.Globalization; using System.Linq.Expressions; @@ -12,6 +11,9 @@ public partial class NumberFilter : IFilter [CascadingParameter(Name = "Column")] public IColumn Column { get; set; } + [Inject] + Microsoft.Extensions.Localization.IStringLocalizer Localization { get; set; } + private NumberCondition Condition { get; set; } private string FilterValue { get; set; } @@ -140,28 +142,28 @@ public Expression> GetFilter() public enum NumberCondition { - [Description("Is equal to")] + [LocalizedDescription("NumberConditionIsEqualTo", typeof(Localization))] IsEqualTo, - [Description("Is not equal to")] + [LocalizedDescription("NumberConditionIsnotEqualTo", typeof(Localization))] IsNotEqualTo, - [Description("Is greater than or equal to")] + [LocalizedDescription("NumberConditionIsGreaterThanOrEqualTo", typeof(Localization))] IsGreaterThanOrEqualTo, - [Description("Is greater than")] + [LocalizedDescription("NumberConditionIsGreaterThan", typeof(Localization))] IsGreaterThan, - [Description("Is less than or equal to")] + [LocalizedDescription("NumberConditionIsLessThanOrEqualTo", typeof(Localization))] IsLessThanOrEqualTo, - [Description("Is less than")] + [LocalizedDescription("NumberConditionIsLessThan", typeof(Localization))] IsLessThan, - [Description("Is null")] + [LocalizedDescription("NumberConditionIsNull", typeof(Localization))] IsNull, - [Description("Is not null")] + [LocalizedDescription("NumberConditionIsNotNull", typeof(Localization))] IsNotNull } } diff --git a/src/BlazorTable/Filters/StringFilter.razor.cs b/src/BlazorTable/Filters/StringFilter.razor.cs index 8e4ae904..4e5b0a40 100644 --- a/src/BlazorTable/Filters/StringFilter.razor.cs +++ b/src/BlazorTable/Filters/StringFilter.razor.cs @@ -1,7 +1,6 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.Extensions.Logging; +using BlazorTable.Components; +using Microsoft.AspNetCore.Components; using System; -using System.ComponentModel; using System.Linq.Expressions; namespace BlazorTable @@ -11,6 +10,9 @@ public partial class StringFilter : IFilter [CascadingParameter(Name = "Column")] public IColumn Column { get; set; } + [Inject] + Microsoft.Extensions.Localization.IStringLocalizer Localization { get; set; } + private StringCondition Condition { get; set; } private string FilterText { get; set; } @@ -185,28 +187,28 @@ public Expression> GetFilter() public enum StringCondition { - [Description("Contains")] + [LocalizedDescription("StringConditionContains", typeof(Localization))] Contains, - [Description("Does not contain")] + [LocalizedDescription("StringConditionDoesNotContain", typeof(Localization))] DoesNotContain, - [Description("Starts with")] + [LocalizedDescription("StringConditionStartsWith", typeof(Localization))] StartsWith, - [Description("Ends with")] + [LocalizedDescription("StringConditionEndsWith", typeof(Localization))] EndsWith, - [Description("Is equal to")] + [LocalizedDescription("StringConditionIsEqualTo", typeof(Localization))] IsEqualTo, - [Description("Is not equal to")] + [LocalizedDescription("StringConditionIsNotEqualTo", typeof(Localization))] IsNotEqualTo, - [Description("Is null or empty")] + [LocalizedDescription("StringConditionIsNullOrEmpty", typeof(Localization))] IsNullOrEmpty, - [Description("Is not null or empty")] + [LocalizedDescription("StringConditionIsNotNullOrEmpty", typeof(Localization))] IsNotNulOrEmpty } } diff --git a/src/BlazorTable/IServiceCollectionExtensions.cs b/src/BlazorTable/IServiceCollectionExtensions.cs new file mode 100644 index 00000000..6ed95cd5 --- /dev/null +++ b/src/BlazorTable/IServiceCollectionExtensions.cs @@ -0,0 +1,12 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace BlazorTable +{ + public static class IServiceCollectionExtensions + { + public static IServiceCollection AddBlazorTable(this IServiceCollection services) + { + return services.AddLocalization(); + } + } +} \ No newline at end of file diff --git a/src/BlazorTable/Interfaces/IColumn.cs b/src/BlazorTable/Interfaces/IColumn.cs index 6ab96d87..8943ebd2 100644 --- a/src/BlazorTable/Interfaces/IColumn.cs +++ b/src/BlazorTable/Interfaces/IColumn.cs @@ -35,6 +35,11 @@ public interface IColumn /// bool Filterable { get; set; } + /// + /// Column can be hidden + /// + bool Hideable { get; set; } + /// /// Set the format for values if no template /// @@ -45,6 +50,12 @@ public interface IColumn /// bool FilterOpen { get; } + /// + /// Column visibility + /// True if current column is visible else false. + /// + bool Visible { get; set; } + /// /// Opens/Closes the Filter Panel /// diff --git a/src/BlazorTable/LocalizedDescriptionAttribute.cs b/src/BlazorTable/LocalizedDescriptionAttribute.cs new file mode 100644 index 00000000..dd8bbee3 --- /dev/null +++ b/src/BlazorTable/LocalizedDescriptionAttribute.cs @@ -0,0 +1,49 @@ +using System; +using System.ComponentModel; +using System.Reflection; +using System.Resources; + +namespace BlazorTable +{ + public class LocalizedDescriptionAttribute : DescriptionAttribute + { + private readonly string _resourceKey; + private readonly ResourceManager _resource; + public LocalizedDescriptionAttribute(string resourceKey, Type resourceType) + { + _resource = new ResourceManager(resourceType); + _resourceKey = resourceKey; + } + + public override string Description + { + get + { + string displayName = _resource.GetString(_resourceKey); + + return string.IsNullOrEmpty(displayName) + ? string.Format("[[{0}]]", _resourceKey) + : displayName; + } + } + } + + public static class EnumExtensions + { + public static string GetDescription(this Enum enumValue) + { + FieldInfo fi = enumValue.GetType().GetField(enumValue.ToString()); + + DescriptionAttribute[] attributes = + (DescriptionAttribute[])fi.GetCustomAttributes( + typeof(DescriptionAttribute), + false); + + if (attributes != null && + attributes.Length > 0) + return attributes[0].Description; + else + return enumValue.ToString(); + } + } +}
    + @if (ShowSearchBar) + { + + } + @if (Columns.Exists(column => !column.Visible)) + { + + +

    Column Visibility

    +
    + + @foreach (IColumn column in Columns.Where(column => !column.Visible)) + { + + + + + } +
    + @(column.Title) + + +
    + +
    +
    + } +
    - -
    - @column.Title - - @if (column.SortColumn) - { - if (column.SortDescending) - { } - else - { } - } - - @if (column.Filterable) - { -
    + +
    + @column.Title + + @if (column.SortColumn) + { + if (column.SortDescending) + { } + else + { } + } + + @if (column.Filterable) + { + + + +

    Filter

    +
    + + + + + + + @if (column.CustomIFilters != null) + { + @column.CustomIFilters(column) + } + +
    +
    +
    + } + + @if (column.Hideable) + { +
    + - -
    - - -

    Filter

    -
    - - - - - - - @if (column.CustomIFilters != null) - { - @column.CustomIFilters(column) - } - -
    -
    -
    - } -
    -
    - + @if (isOpen) {} else @@ -108,17 +161,20 @@ @foreach (IColumn column in Columns) { - - - @if (IsEditMode && column.EditTemplate != null) - @column.EditTemplate(item) - else if (column.Template == null) - @column.Render(item) - else - @column.Template(item) - + + @if (IsEditMode && column.EditTemplate != null) + @column.EditTemplate(item) + else if (column.Template == null) + @column.Render(item) + else + @column.Template(item) +