From 7552b34ced95b6d464fc9c95741ad1cfaff4f59f Mon Sep 17 00:00:00 2001 From: OlgunR Date: Tue, 14 Apr 2026 16:55:14 +0200 Subject: [PATCH] Refactor MassDataGrid to use BandGridBase for layout logic Move band and column management to BandGridBase, reducing duplication in MassDataGrid. Column definitions and layout key are now provided via overridden properties. Band editor actions now use feedback methods for user messages. Grid layout application and error display are streamlined. Improves maintainability and enables reuse across grid components. --- .../Components/MassDataGrid.razor | 248 +++--------------- 1 file changed, 39 insertions(+), 209 deletions(-) diff --git a/DbFirst.BlazorWebApp/Components/MassDataGrid.razor b/DbFirst.BlazorWebApp/Components/MassDataGrid.razor index 5cf80e0..5327217 100644 --- a/DbFirst.BlazorWebApp/Components/MassDataGrid.razor +++ b/DbFirst.BlazorWebApp/Components/MassDataGrid.razor @@ -1,5 +1,5 @@ +@inherits BandGridBase @inject MassDataApiClient Api -@inject BandLayoutService BandLayoutService @if (!string.IsNullOrWhiteSpace(errorMessage)) { @@ -35,8 +35,8 @@ else
- - + +
@foreach (var band in bandLayout.Bands) { @@ -46,7 +46,7 @@ else
} - @foreach (var column in columnDefinitions) + @foreach (var column in ColumnDefinitions) { columnBandAssignments = new(); - private List bandOptions = new(); - private Dictionary columnLookup = new(); - private bool gridLayoutApplied; - private bool bandEditorExpanded; - private List columnDefinitions = new() - { - new() { FieldName = nameof(MassDataReadDto.Id), Caption = "Id", Width = "90px", ReadOnly = true, FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(MassDataReadDto.CustomerName), Caption = "CustomerName", FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(MassDataReadDto.Amount), Caption = "Amount", DisplayFormat = "c2", FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(MassDataReadDto.Category), Caption = "Category", ReadOnly = true, FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(MassDataReadDto.StatusFlag), Caption = "Status", ReadOnly = true, FilterType = ColumnFilterType.Bool }, - new() { FieldName = nameof(MassDataReadDto.AddedWhen), Caption = "Added", ReadOnly = true, FilterType = ColumnFilterType.Date }, - new() { FieldName = nameof(MassDataReadDto.ChangedWhen), Caption = "Changed", ReadOnly = true, FilterType = ColumnFilterType.Date } - }; + protected override string LayoutKey => "MassDataGrid"; + + protected override List ColumnDefinitions { get; } = new() +{ + new() { FieldName = nameof(MassDataReadDto.Id), Caption = "Id", Width = "90px", ReadOnly = true, FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(MassDataReadDto.CustomerName), Caption = "CustomerName", FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(MassDataReadDto.Amount), Caption = "Amount", DisplayFormat = "c2", FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(MassDataReadDto.Category), Caption = "Category", ReadOnly = true, FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(MassDataReadDto.StatusFlag), Caption = "Status", ReadOnly = true, FilterType = ColumnFilterType.Bool }, + new() { FieldName = nameof(MassDataReadDto.AddedWhen), Caption = "Added", ReadOnly = true, FilterType = ColumnFilterType.Date }, + new() { FieldName = nameof(MassDataReadDto.ChangedWhen), Caption = "Changed", ReadOnly = true, FilterType = ColumnFilterType.Date } +}; private readonly List pageSizeOptions = new() { @@ -215,44 +207,15 @@ else new() { Value = 0, Text = "PRMassdata_UpsertByCustomerName" } }; - private bool CanSaveBandLayout => !string.IsNullOrWhiteSpace(layoutUser); - - private SizeMode _sizeMode = SizeMode.Medium; - private static readonly List _sizeModes = Enum.GetValues().ToList(); - - private string FormatSizeText(SizeMode size) => size switch - { - SizeMode.Small => "Klein", - SizeMode.Medium => "Mittel", - SizeMode.Large => "Groß", - _ => size.ToString() - }; - - private void OnSizeChange(DropDownButtonItemClickEventArgs args) - { - _sizeMode = Enum.Parse(args.ItemInfo.Id); - } - protected override async Task OnInitializedAsync() { - columnLookup = columnDefinitions.ToDictionary(c => c.FieldName, StringComparer.OrdinalIgnoreCase); - layoutUser = await BandLayoutService.EnsureLayoutUserAsync(); - bandLayout = await BandLayoutService.LoadBandLayoutAsync(LayoutType, LayoutKey, layoutUser, columnLookup); - columnBandAssignments = BandLayoutService.BuildAssignmentsFromLayout(bandLayout); - ApplyColumnLayoutFromStorage(); - _sizeMode = bandLayout.SizeMode; - UpdateBandOptions(); + await InitializeBandLayoutAsync(); await LoadPage(0); } protected override async Task OnAfterRenderAsync(bool firstRender) { - if (!gridLayoutApplied && gridRef != null && bandLayout.GridLayout != null) - { - gridRef.LoadLayout(bandLayout.GridLayout); - gridLayoutApplied = true; - await InvokeAsync(StateHasChanged); - } + await ApplyGridLayoutAfterRenderAsync(); } private async Task LoadPage(int page) @@ -288,160 +251,6 @@ else await LoadPage(0); } - private async Task SaveLayoutAsync() - { - if (string.IsNullOrWhiteSpace(layoutUser)) - return; - try - { - CaptureColumnLayoutFromGrid(); - await BandLayoutService.SaveBandLayoutAsync(LayoutType, LayoutKey, layoutUser, bandLayout); - infoMessage = "Layout gespeichert."; - errorMessage = null; - } - catch (Exception ex) - { - errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}"; - } - } - - private async Task ResetLayoutAsync() - { - if (string.IsNullOrWhiteSpace(layoutUser)) - return; - await BandLayoutService.ResetBandLayoutAsync(LayoutType, LayoutKey, layoutUser); - bandLayout = new BandLayout(); - columnBandAssignments.Clear(); - UpdateBandOptions(); - foreach (var column in columnDefinitions) - column.Width = null; - columnLookup = columnDefinitions.ToDictionary(c => c.FieldName, StringComparer.OrdinalIgnoreCase); - _sizeMode = SizeMode.Medium; - if (gridRef != null) - gridRef.LoadLayout(new GridPersistentLayout()); - gridLayoutApplied = false; - infoMessage = "Layout zurückgesetzt."; - errorMessage = null; - } - - private void CaptureColumnLayoutFromGrid() - { - if (gridRef == null) return; - var layout = gridRef.SaveLayout(); - bandLayout.GridLayout = layout; - bandLayout.SizeMode = _sizeMode; - var orderedColumns = layout.Columns - .Where(c => !string.IsNullOrWhiteSpace(c.FieldName)) - .OrderBy(c => c.VisibleIndex) - .ToList(); - bandLayout.ColumnOrder = orderedColumns.Select(c => c.FieldName).ToList(); - bandLayout.ColumnWidths = orderedColumns - .Where(c => !string.IsNullOrWhiteSpace(c.Width)) - .ToDictionary(c => c.FieldName, c => c.Width, StringComparer.OrdinalIgnoreCase); - } - - private void ApplyColumnLayoutFromStorage() - { - foreach (var column in columnDefinitions) - { - if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width)) - column.Width = width; - } - columnLookup = columnDefinitions.ToDictionary(c => c.FieldName, StringComparer.OrdinalIgnoreCase); - } - - private void AddBand() - { - bandLayout.Bands.Add(new BandDefinition { Id = Guid.NewGuid().ToString("N"), Caption = "Band" }); - UpdateBandOptions(); - } - - private void RemoveBand(BandDefinition band) - { - bandLayout.Bands.Remove(band); - foreach (var key in columnBandAssignments.Where(p => p.Value == band.Id).Select(p => p.Key).ToList()) - columnBandAssignments.Remove(key); - UpdateBandOptions(); - SyncBandsFromAssignments(); - } - - private void UpdateBandCaption(BandDefinition band, string value) - { - band.Caption = value; - UpdateBandOptions(); - } - - private void UpdateColumnBand(string fieldName, string? bandId) - { - if (string.IsNullOrWhiteSpace(bandId)) - columnBandAssignments.Remove(fieldName); - else - columnBandAssignments[fieldName] = bandId; - SyncBandsFromAssignments(); - } - - private string GetColumnBand(string fieldName) - => columnBandAssignments.TryGetValue(fieldName, out var bandId) ? bandId : string.Empty; - - private void SyncBandsFromAssignments() - { - foreach (var band in bandLayout.Bands) - { - band.Columns = columnDefinitions - .Where(c => columnBandAssignments.TryGetValue(c.FieldName, out var id) && id == band.Id) - .Select(c => c.FieldName) - .ToList(); - } - StateHasChanged(); - } - - private void UpdateBandOptions() - { - bandOptions = new List { new() { Id = string.Empty, Caption = "Ohne Band" } }; - bandOptions.AddRange(bandLayout.Bands.Select(b => new BandOption { Id = b.Id, Caption = b.Caption })); - } - - private RenderFragment RenderColumns() => builder => - { - var seq = 0; - builder.OpenComponent(seq++); - builder.AddAttribute(seq++, "Width", "120px"); - builder.CloseComponent(); - var grouped = bandLayout.Bands.SelectMany(b => b.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase); - foreach (var column in columnDefinitions.Where(c => !grouped.Contains(c.FieldName))) - BuildDataColumn(builder, ref seq, column); - foreach (var band in bandLayout.Bands) - { - if (band.Columns.Count == 0) continue; - builder.OpenComponent(seq++); - builder.AddAttribute(seq++, "Caption", band.Caption); - builder.AddAttribute(seq++, "Columns", (RenderFragment)(bandBuilder => - { - var bandSeq = 0; - foreach (var columnName in band.Columns) - { - if (columnLookup.TryGetValue(columnName, out var column)) - BuildDataColumn(bandBuilder, ref bandSeq, column); - } - })); - builder.CloseComponent(); - } - }; - - private void BuildDataColumn(RenderTreeBuilder builder, ref int seq, ColumnDefinition column) - { - builder.OpenComponent(seq++); - builder.AddAttribute(seq++, "FieldName", column.FieldName); - builder.AddAttribute(seq++, "Caption", column.Caption); - if (!string.IsNullOrWhiteSpace(column.Width)) - builder.AddAttribute(seq++, "Width", column.Width); - if (!string.IsNullOrWhiteSpace(column.DisplayFormat)) - builder.AddAttribute(seq++, "DisplayFormat", column.DisplayFormat); - if (column.ReadOnly) - builder.AddAttribute(seq++, "ReadOnly", true); - builder.CloseComponent(); - } - private void SetEditContext(EditContext context) { if (editContext == context) return; @@ -575,4 +384,25 @@ else public int? Value { get; set; } public string Text { get; set; } = string.Empty; } + + 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; + } } \ No newline at end of file