Add extensible InfoPanel system with custom templates
Introduce a flexible InfoPanel architecture for grid components, allowing per-grid customization via a new InfoPanelType parameter. Add MgInfoPanelTemplateBase for code-based InfoPanel templates with overridable header, content, and footer sections. Support custom templates in MgGridInfoPanel via new RenderFragment parameters. Add MgGridDataColumn for InfoPanel-specific column settings. Demonstrate usage with a custom InfoPanel for ShippingDocument grid. Maintains backward compatibility with default InfoPanel behavior.
This commit is contained in:
parent
fe1a59a0bd
commit
112d633590
|
|
@ -99,6 +99,12 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
|
|||
|
||||
[Parameter] public bool ShowInfoPanel { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Custom InfoPanel component type. Must inherit from MgInfoPanelTemplateBase.
|
||||
/// If not set, the default MgGridInfoPanel is used.
|
||||
/// </summary>
|
||||
[Parameter] public Type? InfoPanelType { get; set; }
|
||||
|
||||
private object _focusedDataItem;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -222,10 +228,13 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
|
|||
panesBuilder.AddAttribute(paneSeq++, "ChildContent", (RenderFragment)(infoPanelBuilder =>
|
||||
{
|
||||
var infoPanelSeq = 0;
|
||||
infoPanelBuilder.OpenComponent<MgGridInfoPanel>(infoPanelSeq++);
|
||||
|
||||
// Use custom InfoPanel type if provided, otherwise use default MgGridInfoPanel
|
||||
var panelType = InfoPanelType ?? typeof(MgGridInfoPanel);
|
||||
infoPanelBuilder.OpenComponent(infoPanelSeq++, panelType);
|
||||
infoPanelBuilder.AddComponentReferenceCapture(infoPanelSeq++, instance =>
|
||||
{
|
||||
InfoPanelInstance = (MgGridInfoPanel)instance;
|
||||
InfoPanelInstance = instance as IInfoPanelBase;
|
||||
});
|
||||
infoPanelBuilder.CloseComponent();
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
using DevExpress.Blazor;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AyCode.Blazor.Components.Components.Grids;
|
||||
|
||||
/// <summary>
|
||||
/// Extended DxGridDataColumn with additional parameters for InfoPanel support.
|
||||
/// </summary>
|
||||
public class MgGridDataColumn : DxGridDataColumn
|
||||
{
|
||||
/// <summary>
|
||||
/// Whether this column should be visible in the InfoPanel. Default is true.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowInInfoPanel { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Custom display format for InfoPanel (overrides DisplayFormat if set).
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? InfoPanelDisplayFormat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Column order in InfoPanel (lower = earlier). Default is int.MaxValue.
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public int InfoPanelOrder { get; set; } = int.MaxValue;
|
||||
}
|
||||
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
<div @ref="_panelElement" class="mg-grid-info-panel @(_isEditMode ? "edit-mode" : "view-mode")">
|
||||
@* Header *@
|
||||
@if (HeaderTemplate != null)
|
||||
{
|
||||
@HeaderTemplate
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="dxbl-grid-header-panel px-3 py-2 border-bottom">
|
||||
<span class="fw-semibold">@((_currentGrid as IMgGridBase)?.Caption ?? "")</span>
|
||||
</div>
|
||||
|
|
@ -15,6 +21,7 @@
|
|||
<MgGridToolbarTemplate Grid="_currentGrid as IMgGridBase" OnlyGridEditTools="true" ShowOnlyIcon="true" />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@* Content *@
|
||||
<div class="mg-info-panel-content">
|
||||
|
|
@ -23,6 +30,12 @@
|
|||
var dataItem = GetActiveDataItem()!;
|
||||
var dataItemType = dataItem.GetType();
|
||||
|
||||
@if (ColumnsTemplate != null)
|
||||
{
|
||||
@ColumnsTemplate
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="mg-info-panel-grid">
|
||||
@foreach (var column in GetVisibleColumns())
|
||||
{
|
||||
|
|
@ -51,6 +64,7 @@
|
|||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-center text-muted py-5">
|
||||
|
|
@ -58,6 +72,12 @@
|
|||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@* Footer *@
|
||||
@if (FooterTemplate != null)
|
||||
{
|
||||
@FooterTemplate
|
||||
}
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,21 @@ public partial class MgGridInfoPanel : ComponentBase, IAsyncDisposable, IInfoPan
|
|||
/// </summary>
|
||||
[Parameter] public bool ShowReadOnlyFieldsInEditMode { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Custom header template. If not set, default header is used.
|
||||
/// </summary>
|
||||
[Parameter] public RenderFragment? HeaderTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Custom columns template. If not set, columns are auto-generated.
|
||||
/// </summary>
|
||||
[Parameter] public RenderFragment? ColumnsTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Custom footer template. If not set, no footer is rendered.
|
||||
/// </summary>
|
||||
[Parameter] public RenderFragment? FooterTemplate { get; set; }
|
||||
|
||||
private ElementReference _panelElement;
|
||||
private bool _isJsInitialized;
|
||||
private const int DefaultTopOffset = 300; // Increased from 180 to account for header + tabs + toolbar
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
@using AyCode.Blazor.Components.Components.Grids
|
||||
|
||||
<MgGridToolbarBase @ref="GridToolbar" Grid="Grid" ItemRenderStyleMode="ToolbarRenderStyleMode.Plain" ShowOnlyIcon="ShowOnlyIcon">
|
||||
<MgGridToolbarBase @ref="GridToolbar" Grid="Grid" ItemRenderStyleMode="ToolbarRenderStyleMode.Plain" ShowOnlyIcon="ShowOnlyIcon">
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "New")" Click="NewItem_Click" IconCssClass="grid-new-row" Visible="@(!IsEditing)" Enabled="@(!IsSyncing)" />
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "Edit")" Click="EditItem_Click" IconCssClass="grid-edit-row" Visible="@(!IsEditing)" Enabled="@(HasFocusedRow && !IsSyncing)" />
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "Delete")" Click="DeleteItem_Click" IconCssClass="grid-delete-row" Visible="@(!IsEditing)" Enabled="@(false && HasFocusedRow && !IsSyncing)" />
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
@if (!OnlyGridEditTools)
|
||||
{
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "Column Chooser")" BeginGroup="true" Click="ColumnChooserItem_Click" IconCssClass="grid-column-chooser" />
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "Export")" IconCssClass="grid-export" Enabled="@(false && HasFocusedRow && !IsEditing)">
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "Export")" IconCssClass="grid-export" Visible="false" Enabled="@(HasFocusedRow && !IsEditing)">
|
||||
<Items>
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "To CSV")" Click="ExportCsvItem_Click" IconCssClass="grid-export-xlsx" />
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "To XLSX")" Click="ExportXlsxItem_Click" IconCssClass="grid-export-xlsx" />
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
<DxToolbarItem BeginGroup="true"></DxToolbarItem>
|
||||
@ToolbarItemsExtended
|
||||
}
|
||||
</MgGridToolbarBase>
|
||||
</MgGridToolbarBase>
|
||||
|
||||
@code {
|
||||
[Parameter] public bool OnlyGridEditTools { get; set; } = false;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AyCode.Blazor.Components.Components.Grids;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for custom InfoPanel templates.
|
||||
/// Inherit from this class to create a custom InfoPanel for a specific grid.
|
||||
/// </summary>
|
||||
public abstract class MgInfoPanelTemplateBase : MgGridInfoPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Override this to provide custom header content.
|
||||
/// Return null to use default header.
|
||||
/// </summary>
|
||||
protected virtual RenderFragment? GetHeaderTemplate() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Override this to provide custom columns/content.
|
||||
/// Return null to use auto-generated columns.
|
||||
/// </summary>
|
||||
protected virtual RenderFragment? GetColumnsTemplate() => null;
|
||||
|
||||
/// <summary>
|
||||
/// Override this to provide custom footer content.
|
||||
/// Return null to hide footer.
|
||||
/// </summary>
|
||||
protected virtual RenderFragment? GetFooterTemplate() => null;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
SetTemplates();
|
||||
base.OnInitialized();
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
SetTemplates();
|
||||
base.OnParametersSet();
|
||||
}
|
||||
|
||||
private void SetTemplates()
|
||||
{
|
||||
HeaderTemplate = GetHeaderTemplate();
|
||||
ColumnsTemplate = GetColumnsTemplate();
|
||||
FooterTemplate = GetFooterTemplate();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue