Skip to content

Commit

Permalink
Expose CellDataType, CellEditor static classes
Browse files Browse the repository at this point in the history
  • Loading branch information
OsamaAlRashed committed Nov 3, 2024
1 parent 9e18921 commit 717fffc
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 44 deletions.
6 changes: 3 additions & 3 deletions Demo/Models/Product.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using Gridazor.Attributes;
using Gridazor.Models;
using Gridazor.Statics;

namespace Gridazor.Demo.Models;

public class Product
{
[Editable(false)]
[Hide]
[Required(false)] // auto generated
[Required(false)]
public Guid Id { get; set; } = Guid.NewGuid();

[RowSelection]
Expand All @@ -19,14 +20,13 @@ public class Product
public DateOnly Date { get; set; }
public DateTime DateTime { get; set; }

[CellEditor("agLargeTextCellEditor")]
[CellEditor(CellEditor.AgLargeTextCellEditor)]
public string? Description { get; set; }

[HeaderName("Category")]
public int CatId { get; set; }

[Required(true)]
[HeaderName("Image")]
public FileInput? Image { get; set; }
public double Price { get; set; }
public int Quantity { get; set; }
Expand Down
27 changes: 27 additions & 0 deletions Demo/Resources/Views.Home.Index.ar.resx
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,31 @@
<data name="Category" xml:space="preserve">
<value>التصنيف</value>
</data>
<data name="Date" xml:space="preserve">
<value>التاريخ</value>
</data>
<data name="DateTime" xml:space="preserve">
<value>التاريخ والوقت</value>
</data>
<data name="Description" xml:space="preserve">
<value>الوصف</value>
</data>
<data name="Image" xml:space="preserve">
<value>الصورة</value>
</data>
<data name="Name" xml:space="preserve">
<value>الاسم</value>
</data>
<data name="Price" xml:space="preserve">
<value>السعر</value>
</data>
<data name="Quality" xml:space="preserve">
<value>النوعية</value>
</data>
<data name="Quantity" xml:space="preserve">
<value>الكمية</value>
</data>
<data name="Selected" xml:space="preserve">
<value>مختارة</value>
</data>
</root>
14 changes: 12 additions & 2 deletions Demo/Views/Home/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
@using Gridazor;
@inject IViewLocalizer viewLocalizer;
@using System.Globalization
@using Gridazor.Attributes
@using Gridazor.Settings
@using Microsoft.AspNetCore.Mvc.Localization
@{
string rtl = CultureInfo.CurrentCulture.TextInfo.IsRightToLeft.ToString().ToLower();
Expand All @@ -18,7 +20,10 @@
<button id="delete-button" type="button" class="btn btn-danger">Delete</button>
</div>
<div class="card-body">
@Html.GridEditorFor(x => x.Products, "myGrid", "ag-theme-quartz")
@Html.GridEditorFor(x => x.Products, "myGrid", "ag-theme-quartz", new Dictionary<string, Func<Column, object>>()
{
{ nameof(HeaderNameAttribute), (column) => viewLocalizer[column.HeaderName].Value },
})
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
Expand All @@ -36,11 +41,16 @@
console.log('@rtl')
const gridazor = new Gridazor(gridElement, {
propertyName: '@nameof(Model.Products)',
localeText: '@rtl' == 'true' ? {
pageSizeSelectorLabel: 'حجم الصفحة:',
page: 'الصفحة',
to: 'إلى',
of: 'من'
} : {},
enableRtl: '@rtl',
overrideColumnDefs: [
{
field: "catId",
headerName: '@viewLocalizer["Category"]',
cellEditor: GridazorDropdown,
cellEditorParams: {
searchUrl: "Home/GetCategories",
Expand Down
4 changes: 2 additions & 2 deletions Gridazor.Tests/IntegrationTests/GridEditorForTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void GridEditorFor_WithValidEnumerableType_ReturnsExpectedHtml()
Expression<Func<TestModel, IEnumerable<TestItem>>> expression = model => model.Items;

var expectedPropertyName = nameof(TestModel.Items);
var expectedColumnDefsJson = JsonSerializer.Serialize(DefaultColumnProvider.Instance.Get(typeof(TestItem)), _jsonOptions);
var expectedColumnDefsJson = JsonSerializer.Serialize(DefaultColumnProvider.Instance.Get(typeof(TestItem), []), _jsonOptions);
var expectedJsonData = JsonSerializer.Serialize(viewData.Model.Items, _jsonOptions);

// Act
Expand Down Expand Up @@ -67,7 +67,7 @@ public void GridEditorFor_WithEmptyEnumerableType_TReturnsExpectedHtml()
};
htmlHelperMock.SetupGet(x => x.ViewData).Returns(viewData);
var expectedPropertyName = nameof(TestModel.Items);
var expectedColumnDefsJson = JsonSerializer.Serialize(DefaultColumnProvider.Instance.Get(typeof(TestItem)), _jsonOptions);
var expectedColumnDefsJson = JsonSerializer.Serialize(DefaultColumnProvider.Instance.Get(typeof(TestItem), []), _jsonOptions);
var expectedJsonData = JsonSerializer.Serialize(viewData.Model.Items, _jsonOptions);

// Act
Expand Down
41 changes: 39 additions & 2 deletions Gridazor.Tests/UnitTests/DefaultColumnProviderTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using FluentAssertions;
using Gridazor.Attributes;
using Gridazor.Core;
using Gridazor.Settings;

namespace Gridazor.Tests.UnitTests;

Expand Down Expand Up @@ -36,7 +37,7 @@ public void Get_ShouldReturnColumnsWithAttributes()
var type = typeof(TestClass);

// Act
var columns = provider.Get(type).ToList();
var columns = provider.Get(type, []).ToList();

// Assert
columns.Should().HaveCount(3);
Expand Down Expand Up @@ -83,7 +84,7 @@ public void Get_ShouldReturnColumnWithDefaultValues()
var type = typeof(DefaultClass);

// Act
var columns = provider.Get(type).ToList();
var columns = provider.Get(type, []).ToList();

// Assert
columns.Should().HaveCount(1);
Expand All @@ -98,5 +99,41 @@ public void Get_ShouldReturnColumnWithDefaultValues()
column.Hide.Should().BeFalse();
column.IsRowSelectable.Should().BeFalse();
}

[Fact]
public void GetWithOverrideMetadataValues_ShouldReturnColumnWithDefaultValues()
{
// Arrange
var provider = DefaultColumnProvider.Instance;
var type = typeof(DefaultClass);

var dic = new Dictionary<string, Func<Column, object>>
{
{ nameof(CellDataTypeAttribute), (column) => "Custom_" + column.CellDataType },
{ nameof(CellEditorAttribute), (column) => "Custom_" + column.CellEditor },
{ nameof(EditableAttribute), (column) => !column.Editable },
{ nameof(FieldAttribute), (column) => "Custom_" + column.Field },
{ nameof(HeaderNameAttribute), (column) => "Custom_" + column.HeaderName },
{ nameof(HideAttribute), (column) => !column.Hide },
{ nameof(RequiredAttribute), (column) => !column.Required },
{ nameof(RowSelectionAttribute), (column) => !column.IsRowSelectable },
};

// Act
var columns = provider.Get(type, dic).ToList();

// Assert
columns.Should().HaveCount(1);

var column = columns.First();
column.CellDataType.Should().Be("Custom_text");
column.CellEditor.Should().Be("Custom_");
column.Editable.Should().BeFalse();
column.Field.Should().Be("Custom_defaultProperty");
column.HeaderName.Should().Be("Custom_DefaultProperty");
column.Hide.Should().BeTrue();
column.Required.Should().BeTrue();
column.IsRowSelectable.Should().BeTrue();
}
}

3 changes: 2 additions & 1 deletion Gridazor/Abstractions/IColumnsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public interface IColumnsProvider
/// Gets a list of metadata for the columns based on the provided type.
/// </summary>
/// <param name="type">The enumerable type.</param>
/// <param name="overrideColumnMetadataValues">override columns</param>
/// <returns>A list of columns containing metadata.</returns>
public IEnumerable<Column> Get(Type type);
public IEnumerable<Column> Get(Type type, Dictionary<string, Func<Column, object>> overrideColumnMetadataValues);
}
49 changes: 47 additions & 2 deletions Gridazor/Core/DefaultColumnProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ internal static DefaultColumnProvider Instance
}
}

public IEnumerable<Column> Get(Type type)
public IEnumerable<Column> Get(Type type, Dictionary<string, Func<Column, object>> overrideColumns)
{
var properties = type.GetProperties();

foreach (var property in properties)
foreach (var property in properties)
{
var column = new Column(property.PropertyType, property.Name);
var customAttributes = property.GetCustomAttributes(true);
Expand Down Expand Up @@ -60,7 +60,52 @@ public IEnumerable<Column> Get(Type type)
}
}

OverrideColumnMetadataValues(overrideColumns, ref column);

yield return column;
}
}

private static void OverrideColumnMetadataValues(Dictionary<string, Func<Column, object>> overrideColumns, ref Column column)
{
if (overrideColumns.TryGetValue(nameof(FieldAttribute), out Func<Column, object>? fieldAttributeFunc))
{
column.SetField((string)fieldAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(HeaderNameAttribute), out Func<Column, object>? headerNameAttributeFunc))
{
column.SetHeaderName((string)headerNameAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(EditableAttribute), out Func<Column, object>? editableAttributeFunc))
{
column.SetEditable((bool)editableAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(CellDataTypeAttribute), out Func<Column, object>? cellDataTypeAttributeFunc))
{
column.SetCellDataType((string)cellDataTypeAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(CellEditorAttribute), out Func<Column, object>? cellEditorAttributeFunc))
{
column.SetCellEditor((string)cellEditorAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(RequiredAttribute), out Func<Column, object>? requiredAttributeFunc))
{
column.SetRequired((bool)requiredAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(HideAttribute), out Func<Column, object>? hideAttributeFunc))
{
column.SetHide((bool)hideAttributeFunc(column));
}

if (overrideColumns.TryGetValue(nameof(RowSelectionAttribute), out Func<Column, object>? rowSelectionAttributeFunc))
{
column.SetIsRowSelectable((bool)rowSelectionAttributeFunc(column));
}
}
}
44 changes: 37 additions & 7 deletions Gridazor/Extensions/GridazorExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Gridazor.Abstractions;
using Gridazor.Core;
using Gridazor.Models;
using Gridazor.Settings;
using Gridazor.Statics;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text.Json;
using static Gridazor.Statics.Constants;

namespace Gridazor;

Expand All @@ -32,32 +33,61 @@ public static class GridazorExtensions
/// <param name="gridId">The unique identifier for the grid.</param>
/// <param name="agGridTheme">The AG Grid theme to apply.</param>
/// <returns>Returns the generated HTML content for the grid editor.</returns>

public static IHtmlContent GridEditorFor<TModel, TResult>(
this IHtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TResult>> expression,
string gridId,
string agGridTheme)
where TResult : class
=> GridEditorFor(htmlHelper, expression, gridId, agGridTheme, null);
=> GridEditorFor(htmlHelper, expression, gridId, agGridTheme, null, new Dictionary<string, Func<Column, object>>());

/// <summary>
/// Generates an HTML grid editor for the specified model property, with an optional custom column provider.
/// Generates an HTML grid editor for the specified model property.
/// </summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <typeparam name="TResult">The result type, which must be a class.</typeparam>
/// <param name="htmlHelper">The HTML helper instance.</param>
/// <param name="expression">The expression representing the model property.</param>
/// <param name="gridId">The unique identifier for the grid.</param>
/// <param name="agGridTheme">The AG Grid theme to apply.</param>
/// <param name="customColumnsProvider">An optional custom column provider.</param>
/// <param name="customColumnsProvider">Custom Columns Provider</param>
/// <returns>Returns the generated HTML content for the grid editor.</returns>
public static IHtmlContent GridEditorFor<TModel, TResult>(
this IHtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TResult>> expression,
string gridId,
string gridId,
string agGridTheme,
IColumnsProvider? customColumnsProvider)
where TResult : class
=> GridEditorFor(htmlHelper, expression, gridId, agGridTheme, customColumnsProvider, new Dictionary<string, Func<Column, object>>());

/// <summary>
/// Generates an HTML grid editor for the specified model property.
/// </summary>
/// <typeparam name="TModel">The model type.</typeparam>
/// <typeparam name="TResult">The result type, which must be a class.</typeparam>
/// <param name="htmlHelper">The HTML helper instance.</param>
/// <param name="expression">The expression representing the model property.</param>
/// <param name="gridId">The unique identifier for the grid.</param>
/// <param name="agGridTheme">The AG Grid theme to apply.</param>
/// <param name="overrideColumnMetadataValues">Dictionary that contaians the metadata</param>
/// <returns>Returns the generated HTML content for the grid editor.</returns>
public static IHtmlContent GridEditorFor<TModel, TResult>(
this IHtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TResult>> expression,
string gridId,
string agGridTheme,
Dictionary<string, Func<Column, object>> overrideColumnMetadataValues)
where TResult : class
=> GridEditorFor(htmlHelper, expression, gridId, agGridTheme, null, overrideColumnMetadataValues);

private static IHtmlContent GridEditorFor<TModel, TResult>(
this IHtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TResult>> expression,
string gridId,
string agGridTheme,
IColumnsProvider? customColumnsProvider,
Dictionary<string, Func<Column, object>> overrideColumnMetadataValues)
where TResult : class
{
ArgumentNullException.ThrowIfNull(nameof(expression));
Expand Down Expand Up @@ -85,7 +115,7 @@ public static IHtmlContent GridEditorFor<TModel, TResult>(
}

var columnsProvider = customColumnsProvider ?? DefaultColumnProvider.Instance;
var columns = columnsProvider.Get(propertyType);
var columns = columnsProvider.Get(propertyType, overrideColumnMetadataValues);

var htmlGenerator = HtmlGenerator.Instance;
var htmlString = htmlGenerator.Generate(
Expand Down
Loading

0 comments on commit 717fffc

Please sign in to comment.