Skip to content

Commit

Permalink
add QueryBuilder
Browse files Browse the repository at this point in the history
  • Loading branch information
pwelter34 committed May 23, 2024
1 parent 8b6f573 commit 98514de
Show file tree
Hide file tree
Showing 42 changed files with 1,599 additions and 109 deletions.
34 changes: 19 additions & 15 deletions samples/Sample.ClientSide/Sample.ClientSide.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>

<IsPackable>false</IsPackable>
</PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Sample.Core\Sample.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Sample.Core\Sample.Core.csproj" />
</ItemGroup>

</Project>
8 changes: 6 additions & 2 deletions samples/Sample.Core/Models/Bank.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;

namespace Sample.Core.Models
{
Expand All @@ -24,5 +24,9 @@ public class Bank

[JsonPropertyName("swift_bic")]
public string SwiftBIC { get; set; }

public bool IsActive { get; set; }

public DateTimeOffset Created { get; set; } = DateTimeOffset.Now;
}
}
}
10 changes: 2 additions & 8 deletions samples/Sample.Core/Pages/DataGrid/Examples/Banks.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@using Sample.Core.Services
@using Sample.Core.Services
@using Sample.Core.Models

@inject RandomDataClient RandomDataClient;
Expand Down Expand Up @@ -29,13 +29,7 @@

protected async override Task OnInitializedAsync()
{
var results = await RandomDataClient.GetBanks();

Data = results;

// triger refresh
StateHasChanged();
await DataGrid.RefreshAsync(true);
Data = await RandomDataClient.GetBanks();
}

private Dictionary<string, object> CellAttributes(Bank bank)
Expand Down
5 changes: 4 additions & 1 deletion samples/Sample.Core/Pages/Index.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@page "/"
@page "/"

<div class="bg-light mb-4 rounded-2 py-5 px-3">
<h1>LoreSoft Blazor Controls</h1>
Expand All @@ -12,6 +12,9 @@

<h2>DataList</h2>
<p><a href="/datalist/index">DataList Control Demo</a> </p>

<h2>QueryBuilder</h2>
<p><a href="/query/index">QueryBuilder Demo</a> </p>
</div>
<div class="col-sm">
<h2>DateTimePicker</h2>
Expand Down
41 changes: 41 additions & 0 deletions samples/Sample.Core/Pages/QueryBuilder/Examples/Basic.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@using LoreSoft.Blazor.Controls.Utilities
@using Sample.Core.Models
@using System.Text.Json

<h3 class="m-2">Basic</h3>

<QueryBuilder TItem="Bank" @bind-Query="Query">
<QueryFields>
<QueryBuilderField Field="p => p.Id" />
<QueryBuilderField Field="p => p.AccountNumber" />
<QueryBuilderField Field="p => p.IBAN" />
<QueryBuilderField Field="p => p.BankName" />
<QueryBuilderField Field="p => p.RoutingNumber" />
<QueryBuilderField Field="p => p.SwiftBIC" />
<QueryBuilderField Field="p => p.IsActive" />
<QueryBuilderField Field="p => p.Created" />
</QueryFields>
</QueryBuilder>
<h4 class="m-2">Query JSON</h4>
<pre style="max-height: 400px; max-width: calc(100vw - 4em);"><code class="language-json">@Serialize(Query)</code></pre>
@code {
protected QueryGroup Query { get; set; } = new()
{
Filters = new List<QueryRule>
{
new QueryFilter{ Field = nameof(Bank.BankName), Operator = QueryOperators.Contains, Value = "Wells Fargo" },
new QueryFilter{ Field = nameof(Bank.IsActive), Operator = QueryOperators.Equal, Value = true },
}
};

protected string Serialize(QueryGroup query)
{
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
options.WriteIndented = true;
return JsonSerializer.Serialize(query, options);
}

}
66 changes: 66 additions & 0 deletions samples/Sample.Core/Pages/QueryBuilder/Examples/Templates.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
@using LoreSoft.Blazor.Controls.Utilities
@using Sample.Core.Models
@using System.Text.Json

<h3 class="m-2">Using Templates</h3>

<QueryBuilder TItem="Bank" @bind-Query="Query">
<QueryFields>
<QueryBuilderField Field="p => p.Id" />
<QueryBuilderField Field="p => p.AccountNumber" />
<QueryBuilderField Field="p => p.IBAN" />
<QueryBuilderField Field="p => p.BankName">
<ValueTemplate Context="filter">
<select value="@Binding.Format(filter.Value)"
@onchange="e => filter.Value = Binding.Convert<string>(e.Value)">
<option>- Select Bank -</option>
<option value="Chase Bank">Chase Bank</option>
<option value="Bank of America">Bank of America</option>
<option value="Wells Fargo">Wells Fargo</option>
<option value="Citibank">Citibank</option>
<option value="U.S. Bank">U.S. Bank</option>
<option value="PNC Bank">PNC Bank</option>
<option value="Goldman Sachs Bank">Goldman Sachs Bank</option>
<option value="Truist Bank">Truist Bank</option>
<option value="Capital One">Capital One</option>
<option value="TD Bank">TD Bank</option>
</select>
</ValueTemplate>
</QueryBuilderField>
<QueryBuilderField Field="p => p.RoutingNumber" />
<QueryBuilderField Field="p => p.SwiftBIC" />
<QueryBuilderField Field="p => p.IsActive" />
<QueryBuilderField Field="p => p.Created" />
</QueryFields>
</QueryBuilder>
<h4 class="m-2">Query JSON</h4>
<pre style="max-height: 400px; max-width: calc(100vw - 4em);"><code class="language-json">@Serialize(Query)</code></pre>
@code {
protected QueryGroup Query { get; set; } = new()
{
Filters = new List<QueryRule>
{
new QueryFilter{ Field = nameof(Bank.BankName), Operator = QueryOperators.Contains, Value = "Wells Fargo" },
new QueryFilter{ Field = nameof(Bank.IsActive), Operator = QueryOperators.Equal, Value = true },
new QueryGroup {
Logic = QueryLogic.Or,
Filters = new List<QueryRule>
{
new QueryFilter{ Field = nameof(Bank.AccountNumber), Operator = QueryOperators.Equal, Value = "88888" },
new QueryFilter{ Field = nameof(Bank.AccountNumber), Operator = QueryOperators.Equal, Value = "99999" },
}
}
}
};

protected string Serialize(QueryGroup query)
{
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
options.WriteIndented = true;
return JsonSerializer.Serialize(query, options);
}

}
27 changes: 27 additions & 0 deletions samples/Sample.Core/Pages/QueryBuilder/Index.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@page "/query/index"
@using Sample.Core.Models
@using System.Text.Json
@using Sample.Core.Pages.QueryBuilder.Examples

@inject IJSRuntime JsRuntime;

<h1>Query Builder</h1>

<p>Query Builder Control</p>

<Instructions></Instructions>

<h2 class="m-3">Examples</h2>

<Basic />

<Templates />

@code {
protected override async Task OnAfterRenderAsync(bool firstRender)

Check warning on line 21 in samples/Sample.Core/Pages/QueryBuilder/Index.razor

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 21 in samples/Sample.Core/Pages/QueryBuilder/Index.razor

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
base.OnAfterRender(firstRender);
//TODO fix highlight, breaks data binding
//await JsRuntime.InvokeAsync<object>("Prism.highlightAll");
}
}
6 changes: 5 additions & 1 deletion samples/Sample.Core/Sample.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bogus" Version="35.5.1" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
Expand Down
3 changes: 2 additions & 1 deletion samples/Sample.Core/Shared/MainMenu.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<nav class="navbar navbar-expand-xl navbar-light bg-light fixed-top">
<nav class="navbar navbar-expand-xl navbar-light bg-light fixed-top">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="logo.png"
Expand All @@ -22,6 +22,7 @@
<div class="dropdown-menu" aria-labelledby="navbar-components">
<NavLink class="dropdown-item" href="/datagrid/index" Match="NavLinkMatch.Prefix">DataGrid</NavLink>
<NavLink class="dropdown-item" href="/datalist/index" Match="NavLinkMatch.Prefix">DataList</NavLink>
<NavLink class="dropdown-item" href="/query/index" Match="NavLinkMatch.Prefix">QueryBuilder</NavLink>
<div class="dropdown-divider"></div>
<NavLink class="dropdown-item" href="/datetimepicker/index" Match="NavLinkMatch.Prefix">DateTimePicker</NavLink>
<div class="dropdown-divider"></div>
Expand Down
Empty file.
6 changes: 3 additions & 3 deletions samples/Sample.ServerSide/Pages/_Host.cshtml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@page "/"
@page "/"

@namespace Sample.ServerSide.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Expand All @@ -20,9 +20,9 @@

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.10.2/css/all.min.css" integrity="sha256-zmfNZmXoNWBMemUOo1XUGFfc0ihGGLYdgtJS3KCr/l0=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.17.1/themes/prism.min.css" integrity="sha256-77qGXu2p8NpfcBpTjw4jsMeQnz0vyh74f5do0cWjQ/Q=" crossorigin="anonymous" />

<link rel="stylesheet" href="~/_content/LoreSoft.Blazor.Controls/BlazorControls.css" asp-append-version="true" />

<link rel="stylesheet" href="~/site.css" asp-append-version="true" />
</head>
<body style="padding-top: 4.5rem;">
Expand Down
8 changes: 6 additions & 2 deletions samples/Sample.ServerSide/Sample.ServerSide.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Sample.Core\Sample.Core.csproj" />
</ItemGroup>
Expand Down
24 changes: 3 additions & 21 deletions src/LoreSoft.Blazor.Controls/DataColumn.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Globalization;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;

using LoreSoft.Blazor.Controls.Extensions;

using Microsoft.AspNetCore.Components;

Expand Down Expand Up @@ -98,7 +98,7 @@ internal string HeaderTitle()
return Title;

var name = PropertyName();
return ToTitle(name);
return name.ToTitle();
}

internal string CellValue(TItem data)
Expand Down Expand Up @@ -151,24 +151,6 @@ private string PropertyName()
return _propertyName;
}

private string ToTitle(string value)
{
if (string.IsNullOrEmpty(value))
return value;

var words = Regex.Matches(value, @"([A-Z][a-z]*)|([0-9]+)");

var spacedName = new StringBuilder();
foreach (Match word in words)
{
if (spacedName.Length > 0)
spacedName.Append(' ');

spacedName.Append(word.Value);
}

return spacedName.ToString();
}

internal Dictionary<string, object> ComputeAttributes(TItem data)
{
Expand Down
Loading

0 comments on commit 98514de

Please sign in to comment.