Refactor grid logic into BandGridBase<TItem> base class
Move shared state and methods from CatalogsGrid and MassDataGrid into BandGridBase<TItem>. This centralizes edit context handling, validation, popup header logic, row editing/deleting, and layout feedback, reducing duplication and improving maintainability. Individual grid components now only override OnEditFieldChanged for custom validation.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
using DbFirst.BlazorWebApp.Services;
|
using DbFirst.BlazorWebApp.Services;
|
||||||
using DevExpress.Blazor;
|
using DevExpress.Blazor;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Forms;
|
||||||
using Microsoft.AspNetCore.Components.Rendering;
|
using Microsoft.AspNetCore.Components.Rendering;
|
||||||
|
|
||||||
namespace DbFirst.BlazorWebApp.Components;
|
namespace DbFirst.BlazorWebApp.Components;
|
||||||
@@ -27,6 +28,15 @@ public abstract class BandGridBase<TItem> : ComponentBase
|
|||||||
protected SizeMode _sizeMode = SizeMode.Medium;
|
protected SizeMode _sizeMode = SizeMode.Medium;
|
||||||
protected static readonly List<SizeMode> _sizeModes = Enum.GetValues<SizeMode>().ToList();
|
protected static readonly List<SizeMode> _sizeModes = Enum.GetValues<SizeMode>().ToList();
|
||||||
|
|
||||||
|
protected string? errorMessage;
|
||||||
|
protected string? infoMessage;
|
||||||
|
protected bool isLoading;
|
||||||
|
protected bool hasLoaded;
|
||||||
|
protected EditContext? editContext;
|
||||||
|
protected ValidationMessageStore? validationMessageStore;
|
||||||
|
protected string popupHeaderText = "Edit";
|
||||||
|
protected int _focusedVisibleIndex;
|
||||||
|
|
||||||
private const string LayoutType = "GRID_BANDS";
|
private const string LayoutType = "GRID_BANDS";
|
||||||
|
|
||||||
// --- Lifecycle ---
|
// --- Lifecycle ---
|
||||||
@@ -216,4 +226,53 @@ public abstract class BandGridBase<TItem> : ComponentBase
|
|||||||
builder.AddAttribute(seq++, "ReadOnly", true);
|
builder.AddAttribute(seq++, "ReadOnly", true);
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void SetEditContext(EditContext context)
|
||||||
|
{
|
||||||
|
if (editContext == context) return;
|
||||||
|
if (editContext != null)
|
||||||
|
editContext.OnFieldChanged -= OnEditFieldChanged;
|
||||||
|
editContext = context;
|
||||||
|
validationMessageStore = new ValidationMessageStore(editContext);
|
||||||
|
editContext.OnFieldChanged += OnEditFieldChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
|
||||||
|
{
|
||||||
|
validationMessageStore?.Clear();
|
||||||
|
editContext?.NotifyValidationStateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void SetPopupHeaderText(bool isNew) => popupHeaderText = isNew ? "Neu" : "Edit";
|
||||||
|
|
||||||
|
protected async Task EditFocusedRow()
|
||||||
|
=> await gridRef!.StartEditRowAsync(_focusedVisibleIndex);
|
||||||
|
|
||||||
|
protected Task DeleteFocusedRow()
|
||||||
|
{
|
||||||
|
gridRef!.ShowRowDeleteConfirmation(_focusedVisibleIndex);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task SaveLayoutWithFeedbackAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await SaveLayoutAsync();
|
||||||
|
infoMessage = "Layout gespeichert.";
|
||||||
|
errorMessage = null;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async Task ResetLayoutWithFeedbackAsync()
|
||||||
|
{
|
||||||
|
await ResetLayoutAsync();
|
||||||
|
infoMessage = "Layout zurückgesetzt.";
|
||||||
|
errorMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -149,14 +149,7 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<CatalogReadDto> items = new();
|
private List<CatalogReadDto> items = new();
|
||||||
private bool isLoading;
|
|
||||||
private bool hasLoaded;
|
|
||||||
private string? errorMessage;
|
|
||||||
private string? infoMessage;
|
|
||||||
private EditContext? editContext;
|
|
||||||
private ValidationMessageStore? validationMessageStore;
|
|
||||||
private int? focusedRowKey;
|
private int? focusedRowKey;
|
||||||
private string popupHeaderText = "Edit";
|
|
||||||
|
|
||||||
protected override string LayoutKey => "CatalogsGrid";
|
protected override string LayoutKey => "CatalogsGrid";
|
||||||
protected override bool ShowCommandColumn => false;
|
protected override bool ShowCommandColumn => false;
|
||||||
@@ -209,17 +202,7 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetEditContext(EditContext context)
|
protected override void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
|
||||||
{
|
|
||||||
if (editContext == context) return;
|
|
||||||
if (editContext != null)
|
|
||||||
editContext.OnFieldChanged -= OnEditFieldChanged;
|
|
||||||
editContext = context;
|
|
||||||
validationMessageStore = new ValidationMessageStore(editContext);
|
|
||||||
editContext.OnFieldChanged += OnEditFieldChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
|
|
||||||
{
|
{
|
||||||
if (validationMessageStore == null || editContext == null) return;
|
if (validationMessageStore == null || editContext == null) return;
|
||||||
|
|
||||||
@@ -237,8 +220,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPopupHeaderText(bool isNew) => popupHeaderText = isNew ? "Neu" : "Edit";
|
|
||||||
|
|
||||||
private void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e)
|
private void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e)
|
||||||
{
|
{
|
||||||
popupHeaderText = e.IsNew ? "Neu" : "Edit";
|
popupHeaderText = e.IsNew ? "Neu" : "Edit";
|
||||||
@@ -378,36 +359,4 @@ else
|
|||||||
public int Value { get; set; }
|
public int Value { get; set; }
|
||||||
public string Text { get; set; } = string.Empty;
|
public string Text { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _focusedVisibleIndex;
|
|
||||||
|
|
||||||
private async Task EditFocusedRow()
|
|
||||||
=> await gridRef!.StartEditRowAsync(_focusedVisibleIndex);
|
|
||||||
|
|
||||||
private Task DeleteFocusedRow()
|
|
||||||
{
|
|
||||||
gridRef!.ShowRowDeleteConfirmation(_focusedVisibleIndex);
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveLayoutWithFeedbackAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await SaveLayoutAsync();
|
|
||||||
infoMessage = "Layout gespeichert.";
|
|
||||||
errorMessage = null;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ResetLayoutWithFeedbackAsync()
|
|
||||||
{
|
|
||||||
await ResetLayoutAsync();
|
|
||||||
infoMessage = "Layout zurückgesetzt.";
|
|
||||||
errorMessage = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -175,16 +175,9 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<MassDataReadDto> items = new();
|
private List<MassDataReadDto> items = new();
|
||||||
private bool isLoading;
|
|
||||||
private bool hasLoaded;
|
|
||||||
private string? errorMessage;
|
|
||||||
private string? infoMessage;
|
|
||||||
private int pageIndex;
|
private int pageIndex;
|
||||||
private int pageCount = 1;
|
private int pageCount = 1;
|
||||||
private int? pageSize = 100;
|
private int? pageSize = 100;
|
||||||
private string popupHeaderText = "Edit";
|
|
||||||
private EditContext? editContext;
|
|
||||||
private ValidationMessageStore? validationMessageStore;
|
|
||||||
private int? focusedRowKey;
|
private int? focusedRowKey;
|
||||||
|
|
||||||
protected override string LayoutKey => "MassDataGrid";
|
protected override string LayoutKey => "MassDataGrid";
|
||||||
@@ -259,17 +252,7 @@ else
|
|||||||
await LoadPage(0);
|
await LoadPage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetEditContext(EditContext context)
|
protected override void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
|
||||||
{
|
|
||||||
if (editContext == context) return;
|
|
||||||
if (editContext != null)
|
|
||||||
editContext.OnFieldChanged -= OnEditFieldChanged;
|
|
||||||
editContext = context;
|
|
||||||
validationMessageStore = new ValidationMessageStore(editContext);
|
|
||||||
editContext.OnFieldChanged += OnEditFieldChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
|
|
||||||
{
|
{
|
||||||
if (validationMessageStore == null || editContext == null) return;
|
if (validationMessageStore == null || editContext == null) return;
|
||||||
if (e.FieldIdentifier.FieldName == nameof(MassDataEditModel.UpdateProcedure))
|
if (e.FieldIdentifier.FieldName == nameof(MassDataEditModel.UpdateProcedure))
|
||||||
@@ -285,8 +268,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPopupHeaderText(bool isNew) => popupHeaderText = isNew ? "Neu" : "Edit";
|
|
||||||
|
|
||||||
private void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e)
|
private void OnCustomizeEditModel(GridCustomizeEditModelEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.IsNew)
|
if (e.IsNew)
|
||||||
@@ -391,36 +372,4 @@ else
|
|||||||
public int? Value { get; set; }
|
public int? Value { get; set; }
|
||||||
public string Text { get; set; } = string.Empty;
|
public string Text { get; set; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int _focusedVisibleIndex;
|
|
||||||
|
|
||||||
private async Task EditFocusedRow()
|
|
||||||
=> await gridRef!.StartEditRowAsync(_focusedVisibleIndex);
|
|
||||||
|
|
||||||
private Task DeleteFocusedRow()
|
|
||||||
{
|
|
||||||
gridRef!.ShowRowDeleteConfirmation(_focusedVisibleIndex);
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveLayoutWithFeedbackAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await SaveLayoutAsync();
|
|
||||||
infoMessage = "Layout gespeichert.";
|
|
||||||
errorMessage = null;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ResetLayoutWithFeedbackAsync()
|
|
||||||
{
|
|
||||||
await ResetLayoutAsync();
|
|
||||||
infoMessage = "Layout zurückgesetzt.";
|
|
||||||
errorMessage = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user