From 13d134df0e0a37d69a6df4768efde20016b4be71 Mon Sep 17 00:00:00 2001 From: OlgunR Date: Tue, 14 Apr 2026 16:37:59 +0200 Subject: [PATCH] Refactor CatalogsGrid to use BandGridBase and async layout ops Refactored CatalogsGrid.razor to inherit from BandGridBase, moving band layout and grid logic into the base class. Updated UI to use new async methods for saving and resetting the layout with user feedback. Removed redundant local fields and methods, centralizing layout management and improving maintainability and code reuse. Error and info messages are now shown after layout operations. --- .../Components/CatalogsGrid.razor | 262 +++--------------- 1 file changed, 39 insertions(+), 223 deletions(-) diff --git a/DbFirst.BlazorWebApp/Components/CatalogsGrid.razor b/DbFirst.BlazorWebApp/Components/CatalogsGrid.razor index 3c5e6eb..c8ba429 100644 --- a/DbFirst.BlazorWebApp/Components/CatalogsGrid.razor +++ b/DbFirst.BlazorWebApp/Components/CatalogsGrid.razor @@ -1,5 +1,5 @@ +@inherits BandGridBase @inject CatalogApiClient Api -@inject BandLayoutService BandLayoutService @if (!string.IsNullOrWhiteSpace(errorMessage)) { @@ -34,8 +34,8 @@ else
- - + +
@foreach (var band in bandLayout.Bands) { @@ -45,7 +45,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(CatalogReadDto.Guid), Caption = "Id", Width = "140px", FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(CatalogReadDto.CatTitle), Caption = "Titel", FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(CatalogReadDto.CatString), Caption = "String", FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(CatalogReadDto.AddedWho), Caption = "Angelegt von", ReadOnly = true, FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(CatalogReadDto.AddedWhen), Caption = "Angelegt am", ReadOnly = true, FilterType = ColumnFilterType.Date }, - new() { FieldName = nameof(CatalogReadDto.ChangedWho), Caption = "Geändert von", ReadOnly = true, FilterType = ColumnFilterType.Text }, - new() { FieldName = nameof(CatalogReadDto.ChangedWhen), Caption = "Geändert am", ReadOnly = true, FilterType = ColumnFilterType.Date } - }; + protected override string LayoutKey => "CatalogsGrid"; + + protected override List ColumnDefinitions { get; } = new() +{ + new() { FieldName = nameof(CatalogReadDto.Guid), Caption = "Id", Width = "140px", FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(CatalogReadDto.CatTitle), Caption = "Titel", FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(CatalogReadDto.CatString), Caption = "String", FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(CatalogReadDto.AddedWho), Caption = "Angelegt von", ReadOnly = true, FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(CatalogReadDto.AddedWhen), Caption = "Angelegt am", ReadOnly = true, FilterType = ColumnFilterType.Date }, + new() { FieldName = nameof(CatalogReadDto.ChangedWho), Caption = "Geändert von", ReadOnly = true, FilterType = ColumnFilterType.Text }, + new() { FieldName = nameof(CatalogReadDto.ChangedWhen),Caption = "Geändert am", ReadOnly = true, FilterType = ColumnFilterType.Date } +}; private readonly List procedureOptions = new() { @@ -178,44 +170,15 @@ else new() { Value = 1, Text = "PRTBMY_CATALOG_SAVE" } }; - 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 LoadCatalogs(); } 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 LoadCatalogs() @@ -238,174 +201,6 @@ else } } - 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 +370,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