Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] CardView Component;fixes #725 #732

Merged
merged 14 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
484 changes: 484 additions & 0 deletions COMET.Web.Common.Tests/Components/CardView/CardViewTestFixture.cs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions COMET.Web.Common/COMET.Web.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@
<PackageReference Include="CDP4ServicesDal-CE" Version="27.4.1" />
<PackageReference Include="CDP4Web-CE" Version="27.4.1" />
<PackageReference Include="DevExpress.Blazor" Version="23.2.9" />
<PackageReference Include="FastMember" Version="1.5.0" />
<PackageReference Include="FluentResults" Version="3.16.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.10" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.10" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
<PackageReference Include="ReactiveUI" Version="20.1.63" />
<PackageReference Include="System.Drawing.Common" Version="8.0.10" />
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.5.0" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
</ItemGroup>

Expand Down
141 changes: 141 additions & 0 deletions COMET.Web.Common/Components/CardView/CardField.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CardField.cs" company="Starion Group S.A.">
// Copyright (c) 2023-2024 Starion Group S.A.
//
// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar
//
// This file is part of CDP4-COMET WEB Community Edition
// The CDP4-COMET WEB Community Edition is the Starion Web Application implementation of ECSS-E-TM-10-25
// Annex A and Annex C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace COMET.Web.Common.Components.CardView
{
using System.Text.RegularExpressions;

using FastMember;

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

/// <summary>
/// A component that represents a data field in a <see cref="CardView{T}"/>'s ItemTemplate
/// </summary>
/// <typeparam name="T"></typeparam>
public class CardField<T> : ComponentBase
{
/// <summary>
/// The <see cref="FastMember.TypeAccessor"/> used to read properties from the instance of T.
/// This is a static property on a generic type, so it will have different static values for each used generic type in the application
/// </summary>
private static TypeAccessor typeAccessor;

Check warning on line 45 in COMET.Web.Common/Components/CardView/CardField.cs

View workflow job for this annotation

GitHub Actions / Build

A static field in a generic type is not shared among instances of different close constructed types. (https://rules.sonarsource.com/csharp/RSPEC-2743)

/// <summary>
/// Initializes the static properties of this <see cref="CardField{T}"/> class
/// </summary>
static CardField()

Check warning on line 50 in COMET.Web.Common/Components/CardView/CardField.cs

View workflow job for this annotation

GitHub Actions / Build

Initialize all 'static fields' inline and remove the 'static constructor'. (https://rules.sonarsource.com/csharp/RSPEC-3963)
{
typeAccessor = TypeAccessor.Create(typeof(T));
}

/// <summary>
/// Gets or sets The parent <see cref="CardView{T}"/>t
/// </summary>
[CascadingParameter(Name="CardView")]
private CardView<T> CardView { get; set; }

/// <summary>
/// The SearchTerm of the <see cref="CardView{T}"/> used to visually show the SearchTerm in this <see cref="CardField{T}"/>
/// </summary>
[CascadingParameter(Name = "SearchTerm")]
private string SearchTerm { get; set; }

/// <summary>
/// Gets or sets the context of this <see cref="CardField{T}"/>
/// </summary>
[Parameter]
public T Context { get; set; }

/// <summary>
/// Gets or sets the FieldName (propertyname of T) to show in the UI
/// </summary>
[Parameter]
public string FieldName { get; set; }

/// <summary>
/// Gets or sets a value indicating that sorting is allowed for this <see cref="CardField{T}"/>
/// </summary>
[Parameter]
public bool AllowSort { get; set; } = true;

/// <summary>
/// Gets or sets a value indicating that searching is allowed for this <see cref="CardField{T}"/>
/// </summary>
[Parameter]
public bool AllowSearch { get; set; } = true;

/// <summary>
/// Method invoked when the component is ready to start, having received its
/// initial parameters from its parent in the render tree.
/// </summary>
protected override void OnInitialized()
{
base.OnInitialized();
this.CardView.InitializeCardField(this);
}

/// <summary>
/// Renders the component to the supplied <see cref="RenderTreeBuilder"/>.
/// </summary>
/// <param name="builder">A <see cref="RenderTreeBuilder"/> that will receive the render output.</param>
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
var value = typeAccessor[this.Context, this.FieldName].ToString();

if (this.AllowSearch && !string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(this.SearchTerm))
{
var separatorPattern = $"({this.SearchTerm})";
var result = Regex.Split(value, separatorPattern, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(30));
var elementCounter = 0;

foreach (var element in result)
{
if (string.Equals(element, this.SearchTerm, StringComparison.OrdinalIgnoreCase))
{
builder.OpenElement(elementCounter, "span");

Check warning on line 120 in COMET.Web.Common/Components/CardView/CardField.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to add validation of parameter 'builder' before using it. (https://rules.sonarsource.com/csharp/RSPEC-3900)
elementCounter++;
builder.AddAttribute(elementCounter, "class", "search-mark");
elementCounter++;
builder.AddContent(elementCounter, element);
elementCounter++;
builder.CloseElement();
}
else
{
builder.AddContent(elementCounter, element);

Check warning on line 130 in COMET.Web.Common/Components/CardView/CardField.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to add validation of parameter 'builder' before using it. (https://rules.sonarsource.com/csharp/RSPEC-3900)
elementCounter++;
}
}
}
else
{
builder.AddContent(0, value);

Check warning on line 137 in COMET.Web.Common/Components/CardView/CardField.cs

View workflow job for this annotation

GitHub Actions / Build

Refactor this method to add validation of parameter 'builder' before using it. (https://rules.sonarsource.com/csharp/RSPEC-3900)
}
}
}
}
61 changes: 61 additions & 0 deletions COMET.Web.Common/Components/CardView/CardView.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<!------------------------------------------------------------------------------
// Copyright (c) 2023-2024 Starion Group S.A.
//
// Authors: Sam Gerené, Alex Vorobiev, Alexander van Delft, Jaime Bernar, Théate Antoine, Nabil Abbar
//
// This file is part of CDP4-COMET WEB Community Edition
// The CDP4-COMET WEB Community Edition is the Starion Web Application implementation of ECSS-E-TM-10-25
// Annex A and Annex C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
------------------------------------------------------------------------------->

@namespace COMET.Web.Common.Components.CardView
lxatstariongroup marked this conversation as resolved.
Show resolved Hide resolved
@typeparam T
@inherits DisposableComponent

<p>
<table>
<tr>
<td id="search-textbox" style="visibility:@(this.AllowSearch ? "block": "hidden");">
<DxTextBox CssClass="inline-search-icon" SizeMode="SizeMode.Medium" BindValueMode="BindValueMode.OnDelayedInput" InputDelay="500" TextChanged="this.OnSearchTextChanged" NullText="Search..." ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto">
</DxTextBox>
</td>
<td id="sort-dropdown" style="visibility:@(this.AllowSort ? "block": "hidden");">
<DxComboBox TData="string" TValue="string" CssClass="inline-sort-icon" FilteringMode="DataGridFilteringMode.Contains" SizeMode="SizeMode.Medium" Data="@this.SortFields" SelectedItemChanged="@( x => this.OnSelectedSortItemChanged(x))"
@bind-Value="@this.SelectedSortField">
</DxComboBox>
</td>
</tr>
</table>
</p>
<div class="container" style="height:calc(100% - 40px); overflow:auto;">
<div class="row">
<Virtualize ItemSize="@this.ItemSize" ItemsProvider="this.LoadItems" @ref="this.virtualize">
<ItemContent>
<div class="col" style="padding-left:0px;margin-left:0px;height:(@this.ItemSize)px;min-width:(@this.MinWidth)px;">
<div class="card @(this.GetSelectedClass(@context))"
@onclick="@(() => this.SelectItem(@context))">
<div class="card-body" style="overflow-y:hidden;overflow-x:hidden">
<CascadingValue Name="CardView" Value = "this">
<CascadingValue Name="SearchTerm" Value="this.SearchTerm">
@this.ItemTemplate(@context)
</CascadingValue>
</CascadingValue>
</div>
</div>
</div>
</ItemContent>
</Virtualize>
</div>
</div>
Loading
Loading