Refactor grid and band layout persistence logic
Unify band and grid layout saving into a single "Layout speichern" action and method. Store the full grid layout in BandLayout, and simplify column/band rendering logic. Apply saved layouts after render for consistency. Remove obsolete ordering logic and update messages for clarity. These changes improve robustness and maintainability of layout persistence in CatalogsGrid and MassDataGrid.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
@using Microsoft.AspNetCore.Components
|
@using Microsoft.AspNetCore.Components
|
||||||
@using Microsoft.AspNetCore.Components.Rendering
|
@using Microsoft.AspNetCore.Components.Rendering
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using DevExpress.Blazor
|
||||||
@inject CatalogApiClient Api
|
@inject CatalogApiClient Api
|
||||||
@inject LayoutApiClient LayoutApi
|
@inject LayoutApiClient LayoutApi
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JsRuntime
|
||||||
@@ -96,8 +97,7 @@ else
|
|||||||
<div class="band-editor">
|
<div class="band-editor">
|
||||||
<div class="band-controls">
|
<div class="band-controls">
|
||||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||||
<DxButton Text="Band-Layout speichern" Click="SaveBandLayoutAsync" Enabled="@CanSaveBandLayout" />
|
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||||
<DxButton Text="Grid-Layout speichern" Click="SaveGridLayoutAsync" Enabled="@CanSaveBandLayout" />
|
|
||||||
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
||||||
</div>
|
</div>
|
||||||
@foreach (var band in bandLayout.Bands)
|
@foreach (var band in bandLayout.Bands)
|
||||||
@@ -211,6 +211,8 @@ else
|
|||||||
|
|
||||||
private bool CanSaveBandLayout => !string.IsNullOrWhiteSpace(layoutUser);
|
private bool CanSaveBandLayout => !string.IsNullOrWhiteSpace(layoutUser);
|
||||||
|
|
||||||
|
private bool gridLayoutApplied;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
||||||
@@ -219,6 +221,16 @@ else
|
|||||||
await LoadCatalogs();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SetEditContext(EditContext context)
|
private void SetEditContext(EditContext context)
|
||||||
{
|
{
|
||||||
if (editContext == context)
|
if (editContext == context)
|
||||||
@@ -457,16 +469,10 @@ else
|
|||||||
|
|
||||||
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
||||||
ApplyColumnLayoutFromStorage();
|
ApplyColumnLayoutFromStorage();
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
UpdateBandOptions();
|
UpdateBandOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveBandLayoutAsync()
|
private async Task SaveLayoutAsync()
|
||||||
{
|
|
||||||
await SaveGridLayoutAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGridLayoutAsync()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
{
|
{
|
||||||
@@ -485,15 +491,39 @@ else
|
|||||||
UserName = layoutUser,
|
UserName = layoutUser,
|
||||||
LayoutData = layoutData
|
LayoutData = layoutData
|
||||||
});
|
});
|
||||||
infoMessage = "Grid-Layout gespeichert.";
|
infoMessage = "Layout gespeichert.";
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
errorMessage = $"Grid-Layout konnte nicht gespeichert werden: {ex.Message}";
|
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CaptureColumnLayoutFromGrid()
|
||||||
|
{
|
||||||
|
if (gridRef == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var layout = gridRef.SaveLayout();
|
||||||
|
bandLayout.GridLayout = layout;
|
||||||
|
|
||||||
|
var orderedColumns = layout.Columns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
||||||
|
.OrderBy(column => column.VisibleIndex)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnOrder = orderedColumns
|
||||||
|
.Select(column => column.FieldName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnWidths = orderedColumns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
||||||
|
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ResetBandLayoutAsync()
|
private async Task ResetBandLayoutAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
@@ -510,17 +540,6 @@ else
|
|||||||
|
|
||||||
private void ApplyColumnLayoutFromStorage()
|
private void ApplyColumnLayoutFromStorage()
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnOrder.Count > 0)
|
|
||||||
{
|
|
||||||
var ordered = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.Select(field => columnLookup[field])
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
ordered.AddRange(columnDefinitions.Where(column => !ordered.Contains(column)));
|
|
||||||
columnDefinitions = ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
foreach (var column in columnDefinitions)
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
||||||
@@ -532,30 +551,6 @@ else
|
|||||||
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureColumnLayoutFromGrid()
|
|
||||||
{
|
|
||||||
if (gridRef == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gridColumns = gridRef.GetColumns()
|
|
||||||
.OfType<IGridDataColumn>()
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnOrder = gridColumns
|
|
||||||
.OrderBy(column => column.VisibleIndex)
|
|
||||||
.Select(column => column.FieldName)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnWidths = gridColumns
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
|
||||||
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyBandOrderingFromColumnOrder()
|
private void ApplyBandOrderingFromColumnOrder()
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnOrder.Count == 0)
|
if (bandLayout.ColumnOrder.Count == 0)
|
||||||
@@ -671,6 +666,8 @@ else
|
|||||||
{
|
{
|
||||||
layout ??= new BandLayout();
|
layout ??= new BandLayout();
|
||||||
layout.Bands ??= new List<BandDefinition>();
|
layout.Bands ??= new List<BandDefinition>();
|
||||||
|
layout.ColumnOrder ??= new List<string>();
|
||||||
|
layout.ColumnWidths ??= new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var band in layout.Bands)
|
foreach (var band in layout.Bands)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(band.Id))
|
if (string.IsNullOrWhiteSpace(band.Id))
|
||||||
@@ -710,88 +707,15 @@ else
|
|||||||
builder.AddAttribute(seq++, "Width", "120px");
|
builder.AddAttribute(seq++, "Width", "120px");
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
|
|
||||||
var bandLookup = bandLayout.Bands.ToDictionary(band => band.Id, StringComparer.OrdinalIgnoreCase);
|
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||||
var renderedBands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
||||||
var orderedFields = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (orderedFields.Count == 0)
|
|
||||||
{
|
{
|
||||||
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
BuildDataColumn(builder, ref seq, column);
|
||||||
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
|
||||||
{
|
|
||||||
if (band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var fieldName in orderedFields)
|
|
||||||
{
|
|
||||||
if (columnBandAssignments.TryGetValue(fieldName, out var bandId) && bandLookup.TryGetValue(bandId, out var band))
|
|
||||||
{
|
|
||||||
if (!renderedBands.Add(bandId) || band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
else if (columnLookup.TryGetValue(fieldName, out var column))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
|
||||||
{
|
|
||||||
if (!orderedFields.Contains(column.FieldName, StringComparer.OrdinalIgnoreCase) &&
|
|
||||||
(!columnBandAssignments.TryGetValue(column.FieldName, out var bandId) || !bandLookup.ContainsKey(bandId)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
foreach (var band in bandLayout.Bands)
|
||||||
{
|
{
|
||||||
if (renderedBands.Contains(band.Id) || band.Columns.Count == 0)
|
if (band.Columns.Count == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -856,6 +780,7 @@ else
|
|||||||
public List<BandDefinition> Bands { get; set; } = new();
|
public List<BandDefinition> Bands { get; set; } = new();
|
||||||
public List<string> ColumnOrder { get; set; } = new();
|
public List<string> ColumnOrder { get; set; } = new();
|
||||||
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
public GridPersistentLayout? GridLayout { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class BandDefinition
|
private sealed class BandDefinition
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@using Microsoft.AspNetCore.Components
|
@using Microsoft.AspNetCore.Components
|
||||||
@using Microsoft.AspNetCore.Components.Rendering
|
@using Microsoft.AspNetCore.Components.Rendering
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using DevExpress.Blazor
|
||||||
@inject MassDataApiClient Api
|
@inject MassDataApiClient Api
|
||||||
@inject LayoutApiClient LayoutApi
|
@inject LayoutApiClient LayoutApi
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JsRuntime
|
||||||
@@ -131,8 +132,7 @@ else
|
|||||||
<div class="band-editor">
|
<div class="band-editor">
|
||||||
<div class="band-controls">
|
<div class="band-controls">
|
||||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||||
<DxButton Text="Band-Layout speichern" Click="SaveBandLayoutAsync" Enabled="@CanSaveBandLayout" />
|
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||||
<DxButton Text="Grid-Layout speichern" Click="SaveGridLayoutAsync" Enabled="@CanSaveBandLayout" />
|
|
||||||
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
||||||
</div>
|
</div>
|
||||||
@foreach (var band in bandLayout.Bands)
|
@foreach (var band in bandLayout.Bands)
|
||||||
@@ -353,16 +353,10 @@ else
|
|||||||
|
|
||||||
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
||||||
ApplyColumnLayoutFromStorage();
|
ApplyColumnLayoutFromStorage();
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
UpdateBandOptions();
|
UpdateBandOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveBandLayoutAsync()
|
private async Task SaveLayoutAsync()
|
||||||
{
|
|
||||||
await SaveGridLayoutAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGridLayoutAsync()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
{
|
{
|
||||||
@@ -381,15 +375,39 @@ else
|
|||||||
UserName = layoutUser,
|
UserName = layoutUser,
|
||||||
LayoutData = layoutData
|
LayoutData = layoutData
|
||||||
});
|
});
|
||||||
infoMessage = "Grid-Layout gespeichert.";
|
infoMessage = "Layout gespeichert.";
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
errorMessage = $"Grid-Layout konnte nicht gespeichert werden: {ex.Message}";
|
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CaptureColumnLayoutFromGrid()
|
||||||
|
{
|
||||||
|
if (gridRef == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var layout = gridRef.SaveLayout();
|
||||||
|
bandLayout.GridLayout = layout;
|
||||||
|
|
||||||
|
var orderedColumns = layout.Columns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
||||||
|
.OrderBy(column => column.VisibleIndex)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnOrder = orderedColumns
|
||||||
|
.Select(column => column.FieldName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnWidths = orderedColumns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
||||||
|
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ResetBandLayoutAsync()
|
private async Task ResetBandLayoutAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
@@ -406,17 +424,6 @@ else
|
|||||||
|
|
||||||
private void ApplyColumnLayoutFromStorage()
|
private void ApplyColumnLayoutFromStorage()
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnOrder.Count > 0)
|
|
||||||
{
|
|
||||||
var ordered = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.Select(field => columnLookup[field])
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
ordered.AddRange(columnDefinitions.Where(column => !ordered.Contains(column)));
|
|
||||||
columnDefinitions = ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
foreach (var column in columnDefinitions)
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
||||||
@@ -428,73 +435,6 @@ else
|
|||||||
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureColumnLayoutFromGrid()
|
|
||||||
{
|
|
||||||
if (gridRef == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gridColumns = gridRef.GetColumns()
|
|
||||||
.OfType<IGridDataColumn>()
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnOrder = gridColumns
|
|
||||||
.OrderBy(column => column.VisibleIndex)
|
|
||||||
.Select(column => column.FieldName)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnWidths = gridColumns
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
|
||||||
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyBandOrderingFromColumnOrder()
|
|
||||||
{
|
|
||||||
if (bandLayout.ColumnOrder.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bandById = bandLayout.Bands.ToDictionary(band => band.Id, StringComparer.OrdinalIgnoreCase);
|
|
||||||
var orderedBandIds = new List<string>();
|
|
||||||
var orderedColumnsByBand = bandLayout.Bands.ToDictionary(
|
|
||||||
band => band.Id,
|
|
||||||
_ => new List<string>(),
|
|
||||||
StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
foreach (var field in bandLayout.ColumnOrder)
|
|
||||||
{
|
|
||||||
if (columnBandAssignments.TryGetValue(field, out var bandId) && bandById.ContainsKey(bandId))
|
|
||||||
{
|
|
||||||
if (!orderedBandIds.Contains(bandId, StringComparer.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
orderedBandIds.Add(bandId);
|
|
||||||
}
|
|
||||||
|
|
||||||
orderedColumnsByBand[bandId].Add(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
|
||||||
{
|
|
||||||
var orderedColumns = orderedColumnsByBand[band.Id];
|
|
||||||
orderedColumns.AddRange(band.Columns.Where(column => !orderedColumns.Contains(column, StringComparer.OrdinalIgnoreCase)));
|
|
||||||
band.Columns = orderedColumns;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orderedBandIds.Count > 0)
|
|
||||||
{
|
|
||||||
bandLayout.Bands = orderedBandIds
|
|
||||||
.Select(id => bandById[id])
|
|
||||||
.Concat(bandLayout.Bands.Where(band => !orderedBandIds.Contains(band.Id, StringComparer.OrdinalIgnoreCase)))
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddBand()
|
private void AddBand()
|
||||||
{
|
{
|
||||||
bandLayout.Bands.Add(new BandDefinition
|
bandLayout.Bands.Add(new BandDefinition
|
||||||
@@ -581,6 +521,8 @@ else
|
|||||||
{
|
{
|
||||||
layout ??= new BandLayout();
|
layout ??= new BandLayout();
|
||||||
layout.Bands ??= new List<BandDefinition>();
|
layout.Bands ??= new List<BandDefinition>();
|
||||||
|
layout.ColumnOrder ??= new List<string>();
|
||||||
|
layout.ColumnWidths ??= new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var band in layout.Bands)
|
foreach (var band in layout.Bands)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(band.Id))
|
if (string.IsNullOrWhiteSpace(band.Id))
|
||||||
@@ -606,88 +548,15 @@ else
|
|||||||
builder.AddAttribute(seq++, "Width", "120px");
|
builder.AddAttribute(seq++, "Width", "120px");
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
|
|
||||||
var bandLookup = bandLayout.Bands.ToDictionary(band => band.Id, StringComparer.OrdinalIgnoreCase);
|
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||||
var renderedBands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
||||||
var orderedFields = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (orderedFields.Count == 0)
|
|
||||||
{
|
{
|
||||||
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
BuildDataColumn(builder, ref seq, column);
|
||||||
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
|
||||||
{
|
|
||||||
if (band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var fieldName in orderedFields)
|
|
||||||
{
|
|
||||||
if (columnBandAssignments.TryGetValue(fieldName, out var bandId) && bandLookup.TryGetValue(bandId, out var band))
|
|
||||||
{
|
|
||||||
if (!renderedBands.Add(bandId) || band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
else if (columnLookup.TryGetValue(fieldName, out var column))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
|
||||||
{
|
|
||||||
if (!orderedFields.Contains(column.FieldName, StringComparer.OrdinalIgnoreCase) &&
|
|
||||||
(!columnBandAssignments.TryGetValue(column.FieldName, out var bandId) || !bandLookup.ContainsKey(bandId)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
foreach (var band in bandLayout.Bands)
|
||||||
{
|
{
|
||||||
if (renderedBands.Contains(band.Id) || band.Columns.Count == 0)
|
if (band.Columns.Count == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -873,6 +742,7 @@ else
|
|||||||
public List<BandDefinition> Bands { get; set; } = new();
|
public List<BandDefinition> Bands { get; set; } = new();
|
||||||
public List<string> ColumnOrder { get; set; } = new();
|
public List<string> ColumnOrder { get; set; } = new();
|
||||||
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
public GridPersistentLayout? GridLayout { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class BandDefinition
|
private sealed class BandDefinition
|
||||||
@@ -934,4 +804,16 @@ 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 bool gridLayoutApplied;
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (!gridLayoutApplied && gridRef != null && bandLayout.GridLayout != null)
|
||||||
|
{
|
||||||
|
gridRef.LoadLayout(bandLayout.GridLayout);
|
||||||
|
gridLayoutApplied = true;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@using Microsoft.AspNetCore.Components
|
@using Microsoft.AspNetCore.Components
|
||||||
@using Microsoft.AspNetCore.Components.Rendering
|
@using Microsoft.AspNetCore.Components.Rendering
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using DevExpress.Blazor
|
||||||
@inject CatalogApiClient Api
|
@inject CatalogApiClient Api
|
||||||
@inject LayoutApiClient LayoutApi
|
@inject LayoutApiClient LayoutApi
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JsRuntime
|
||||||
@@ -55,8 +56,7 @@ else
|
|||||||
<div class="band-editor">
|
<div class="band-editor">
|
||||||
<div class="band-controls">
|
<div class="band-controls">
|
||||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||||
<DxButton Text="Band-Layout speichern" Click="SaveBandLayoutAsync" Enabled="@CanSaveBandLayout" />
|
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||||
<DxButton Text="Grid-Layout speichern" Click="SaveGridLayoutAsync" Enabled="@CanSaveBandLayout" />
|
|
||||||
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
||||||
</div>
|
</div>
|
||||||
@foreach (var band in bandLayout.Bands)
|
@foreach (var band in bandLayout.Bands)
|
||||||
@@ -394,12 +394,7 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveBandLayoutAsync()
|
private async Task SaveLayoutAsync()
|
||||||
{
|
|
||||||
await SaveGridLayoutAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGridLayoutAsync()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
{
|
{
|
||||||
@@ -418,15 +413,39 @@ else
|
|||||||
UserName = layoutUser,
|
UserName = layoutUser,
|
||||||
LayoutData = layoutData
|
LayoutData = layoutData
|
||||||
});
|
});
|
||||||
infoMessage = "Grid-Layout gespeichert.";
|
infoMessage = "Layout gespeichert.";
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
errorMessage = $"Grid-Layout konnte nicht gespeichert werden: {ex.Message}";
|
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CaptureColumnLayoutFromGrid()
|
||||||
|
{
|
||||||
|
if (gridRef == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var layout = gridRef.SaveLayout();
|
||||||
|
bandLayout.GridLayout = layout;
|
||||||
|
|
||||||
|
var orderedColumns = layout.Columns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
||||||
|
.OrderBy(column => column.VisibleIndex)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnOrder = orderedColumns
|
||||||
|
.Select(column => column.FieldName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnWidths = orderedColumns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
||||||
|
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task LoadBandLayoutAsync()
|
private async Task LoadBandLayoutAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
@@ -449,77 +468,9 @@ else
|
|||||||
|
|
||||||
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
||||||
ApplyColumnLayoutFromStorage();
|
ApplyColumnLayoutFromStorage();
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
UpdateBandOptions();
|
UpdateBandOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureColumnLayoutFromGrid()
|
|
||||||
{
|
|
||||||
if (gridRef == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gridColumns = gridRef.GetColumns()
|
|
||||||
.OfType<IGridDataColumn>()
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnOrder = gridColumns
|
|
||||||
.OrderBy(column => column.VisibleIndex)
|
|
||||||
.Select(column => column.FieldName)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnWidths = gridColumns
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
|
||||||
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyBandOrderingFromColumnOrder()
|
|
||||||
{
|
|
||||||
if (bandLayout.ColumnOrder.Count == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bandById = bandLayout.Bands.ToDictionary(band => band.Id, StringComparer.OrdinalIgnoreCase);
|
|
||||||
var orderedBandIds = new List<string>();
|
|
||||||
var orderedColumnsByBand = bandLayout.Bands.ToDictionary(
|
|
||||||
band => band.Id,
|
|
||||||
_ => new List<string>(),
|
|
||||||
StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
foreach (var field in bandLayout.ColumnOrder)
|
|
||||||
{
|
|
||||||
if (columnBandAssignments.TryGetValue(field, out var bandId) && bandById.ContainsKey(bandId))
|
|
||||||
{
|
|
||||||
if (!orderedBandIds.Contains(bandId, StringComparer.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
orderedBandIds.Add(bandId);
|
|
||||||
}
|
|
||||||
|
|
||||||
orderedColumnsByBand[bandId].Add(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
|
||||||
{
|
|
||||||
var orderedColumns = orderedColumnsByBand[band.Id];
|
|
||||||
orderedColumns.AddRange(band.Columns.Where(column => !orderedColumns.Contains(column, StringComparer.OrdinalIgnoreCase)));
|
|
||||||
band.Columns = orderedColumns;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orderedBandIds.Count > 0)
|
|
||||||
{
|
|
||||||
bandLayout.Bands = orderedBandIds
|
|
||||||
.Select(id => bandById[id])
|
|
||||||
.Concat(bandLayout.Bands.Where(band => !orderedBandIds.Contains(band.Id, StringComparer.OrdinalIgnoreCase)))
|
|
||||||
.ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddBand()
|
private void AddBand()
|
||||||
{
|
{
|
||||||
bandLayout.Bands.Add(new BandDefinition
|
bandLayout.Bands.Add(new BandDefinition
|
||||||
@@ -592,6 +543,8 @@ else
|
|||||||
{
|
{
|
||||||
layout ??= new BandLayout();
|
layout ??= new BandLayout();
|
||||||
layout.Bands ??= new List<BandDefinition>();
|
layout.Bands ??= new List<BandDefinition>();
|
||||||
|
layout.ColumnOrder ??= new List<string>();
|
||||||
|
layout.ColumnWidths ??= new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var band in layout.Bands)
|
foreach (var band in layout.Bands)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(band.Id))
|
if (string.IsNullOrWhiteSpace(band.Id))
|
||||||
@@ -631,88 +584,15 @@ else
|
|||||||
builder.AddAttribute(seq++, "Width", "120px");
|
builder.AddAttribute(seq++, "Width", "120px");
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
|
|
||||||
var bandLookup = bandLayout.Bands.ToDictionary(band => band.Id, StringComparer.OrdinalIgnoreCase);
|
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||||
var renderedBands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
||||||
var orderedFields = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (orderedFields.Count == 0)
|
|
||||||
{
|
{
|
||||||
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
BuildDataColumn(builder, ref seq, column);
|
||||||
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
|
||||||
{
|
|
||||||
if (band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var fieldName in orderedFields)
|
|
||||||
{
|
|
||||||
if (columnBandAssignments.TryGetValue(fieldName, out var bandId) && bandLookup.TryGetValue(bandId, out var band))
|
|
||||||
{
|
|
||||||
if (!renderedBands.Add(bandId) || band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
else if (columnLookup.TryGetValue(fieldName, out var column))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
|
||||||
{
|
|
||||||
if (!orderedFields.Contains(column.FieldName, StringComparer.OrdinalIgnoreCase) &&
|
|
||||||
(!columnBandAssignments.TryGetValue(column.FieldName, out var bandId) || !bandLookup.ContainsKey(bandId)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
foreach (var band in bandLayout.Bands)
|
||||||
{
|
{
|
||||||
if (renderedBands.Contains(band.Id) || band.Columns.Count == 0)
|
if (band.Columns.Count == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -762,6 +642,7 @@ else
|
|||||||
public List<BandDefinition> Bands { get; set; } = new();
|
public List<BandDefinition> Bands { get; set; } = new();
|
||||||
public List<string> ColumnOrder { get; set; } = new();
|
public List<string> ColumnOrder { get; set; } = new();
|
||||||
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
public GridPersistentLayout? GridLayout { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class BandDefinition
|
private sealed class BandDefinition
|
||||||
@@ -825,17 +706,6 @@ else
|
|||||||
|
|
||||||
private void ApplyColumnLayoutFromStorage()
|
private void ApplyColumnLayoutFromStorage()
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnOrder.Count > 0)
|
|
||||||
{
|
|
||||||
var ordered = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.Select(field => columnLookup[field])
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
ordered.AddRange(columnDefinitions.Where(column => !ordered.Contains(column)));
|
|
||||||
columnDefinitions = ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
foreach (var column in columnDefinitions)
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
||||||
@@ -846,4 +716,16 @@ else
|
|||||||
|
|
||||||
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
columnLookup = columnDefinitions.ToDictionary(column => column.FieldName, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool gridLayoutApplied;
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (!gridLayoutApplied && gridRef != null && bandLayout.GridLayout != null)
|
||||||
|
{
|
||||||
|
gridRef.LoadLayout(bandLayout.GridLayout);
|
||||||
|
gridLayoutApplied = true;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
@using Microsoft.AspNetCore.Components
|
@using Microsoft.AspNetCore.Components
|
||||||
@using Microsoft.AspNetCore.Components.Rendering
|
@using Microsoft.AspNetCore.Components.Rendering
|
||||||
@using Microsoft.AspNetCore.Components.Forms
|
@using Microsoft.AspNetCore.Components.Forms
|
||||||
|
@using DevExpress.Blazor
|
||||||
@inject MassDataApiClient Api
|
@inject MassDataApiClient Api
|
||||||
@inject LayoutApiClient LayoutApi
|
@inject LayoutApiClient LayoutApi
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JsRuntime
|
||||||
@@ -131,8 +132,7 @@ else
|
|||||||
<div class="band-editor">
|
<div class="band-editor">
|
||||||
<div class="band-controls">
|
<div class="band-controls">
|
||||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||||
<DxButton Text="Band-Layout speichern" Click="SaveBandLayoutAsync" Enabled="@CanSaveBandLayout" />
|
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||||
<DxButton Text="Grid-Layout speichern" Click="SaveGridLayoutAsync" Enabled="@CanSaveBandLayout" />
|
|
||||||
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
<DxButton Text="Band-Layout zurücksetzen" Click="ResetBandLayoutAsync" />
|
||||||
</div>
|
</div>
|
||||||
@foreach (var band in bandLayout.Bands)
|
@foreach (var band in bandLayout.Bands)
|
||||||
@@ -353,16 +353,11 @@ else
|
|||||||
|
|
||||||
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
columnBandAssignments = BuildAssignmentsFromLayout(bandLayout);
|
||||||
ApplyColumnLayoutFromStorage();
|
ApplyColumnLayoutFromStorage();
|
||||||
ApplyBandOrderingFromColumnOrder();
|
//ApplyBandOrderingFromColumnOrder();
|
||||||
UpdateBandOptions();
|
UpdateBandOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveBandLayoutAsync()
|
private async Task SaveLayoutAsync()
|
||||||
{
|
|
||||||
await SaveGridLayoutAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveGridLayoutAsync()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
{
|
{
|
||||||
@@ -381,15 +376,39 @@ else
|
|||||||
UserName = layoutUser,
|
UserName = layoutUser,
|
||||||
LayoutData = layoutData
|
LayoutData = layoutData
|
||||||
});
|
});
|
||||||
infoMessage = "Grid-Layout gespeichert.";
|
infoMessage = "Layout gespeichert.";
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
errorMessage = $"Grid-Layout konnte nicht gespeichert werden: {ex.Message}";
|
errorMessage = $"Layout konnte nicht gespeichert werden: {ex.Message}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CaptureColumnLayoutFromGrid()
|
||||||
|
{
|
||||||
|
if (gridRef == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var layout = gridRef.SaveLayout();
|
||||||
|
bandLayout.GridLayout = layout;
|
||||||
|
|
||||||
|
var orderedColumns = layout.Columns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
||||||
|
.OrderBy(column => column.VisibleIndex)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnOrder = orderedColumns
|
||||||
|
.Select(column => column.FieldName)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
bandLayout.ColumnWidths = orderedColumns
|
||||||
|
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
||||||
|
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ResetBandLayoutAsync()
|
private async Task ResetBandLayoutAsync()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||||
@@ -404,30 +423,6 @@ else
|
|||||||
infoMessage = "Band-Layout zurückgesetzt.";
|
infoMessage = "Band-Layout zurückgesetzt.";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CaptureColumnLayoutFromGrid()
|
|
||||||
{
|
|
||||||
if (gridRef == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var gridColumns = gridRef.GetColumns()
|
|
||||||
.OfType<IGridDataColumn>()
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.FieldName))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnOrder = gridColumns
|
|
||||||
.OrderBy(column => column.VisibleIndex)
|
|
||||||
.Select(column => column.FieldName)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
bandLayout.ColumnWidths = gridColumns
|
|
||||||
.Where(column => !string.IsNullOrWhiteSpace(column.Width))
|
|
||||||
.ToDictionary(column => column.FieldName, column => column.Width, StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
ApplyBandOrderingFromColumnOrder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyBandOrderingFromColumnOrder()
|
private void ApplyBandOrderingFromColumnOrder()
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnOrder.Count == 0)
|
if (bandLayout.ColumnOrder.Count == 0)
|
||||||
@@ -473,17 +468,6 @@ else
|
|||||||
|
|
||||||
private void ApplyColumnLayoutFromStorage()
|
private void ApplyColumnLayoutFromStorage()
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnOrder.Count > 0)
|
|
||||||
{
|
|
||||||
var ordered = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.Select(field => columnLookup[field])
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
ordered.AddRange(columnDefinitions.Where(column => !ordered.Contains(column)));
|
|
||||||
columnDefinitions = ordered;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
foreach (var column in columnDefinitions)
|
||||||
{
|
{
|
||||||
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
if (bandLayout.ColumnWidths.TryGetValue(column.FieldName, out var width) && !string.IsNullOrWhiteSpace(width))
|
||||||
@@ -581,6 +565,8 @@ else
|
|||||||
{
|
{
|
||||||
layout ??= new BandLayout();
|
layout ??= new BandLayout();
|
||||||
layout.Bands ??= new List<BandDefinition>();
|
layout.Bands ??= new List<BandDefinition>();
|
||||||
|
layout.ColumnOrder ??= new List<string>();
|
||||||
|
layout.ColumnWidths ??= new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
|
||||||
foreach (var band in layout.Bands)
|
foreach (var band in layout.Bands)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(band.Id))
|
if (string.IsNullOrWhiteSpace(band.Id))
|
||||||
@@ -606,88 +592,15 @@ else
|
|||||||
builder.AddAttribute(seq++, "Width", "120px");
|
builder.AddAttribute(seq++, "Width", "120px");
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
|
|
||||||
var bandLookup = bandLayout.Bands.ToDictionary(band => band.Id, StringComparer.OrdinalIgnoreCase);
|
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||||
var renderedBands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
||||||
var orderedFields = bandLayout.ColumnOrder
|
|
||||||
.Where(columnLookup.ContainsKey)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
if (orderedFields.Count == 0)
|
|
||||||
{
|
{
|
||||||
var grouped = bandLayout.Bands.SelectMany(band => band.Columns).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
BuildDataColumn(builder, ref seq, column);
|
||||||
foreach (var column in columnDefinitions.Where(column => !grouped.Contains(column.FieldName)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
|
||||||
{
|
|
||||||
if (band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var fieldName in orderedFields)
|
|
||||||
{
|
|
||||||
if (columnBandAssignments.TryGetValue(fieldName, out var bandId) && bandLookup.TryGetValue(bandId, out var band))
|
|
||||||
{
|
|
||||||
if (!renderedBands.Add(bandId) || band.Columns.Count == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.OpenComponent<DxGridBandColumn>(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();
|
|
||||||
}
|
|
||||||
else if (columnLookup.TryGetValue(fieldName, out var column))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var column in columnDefinitions)
|
|
||||||
{
|
|
||||||
if (!orderedFields.Contains(column.FieldName, StringComparer.OrdinalIgnoreCase) &&
|
|
||||||
(!columnBandAssignments.TryGetValue(column.FieldName, out var bandId) || !bandLookup.ContainsKey(bandId)))
|
|
||||||
{
|
|
||||||
BuildDataColumn(builder, ref seq, column);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var band in bandLayout.Bands)
|
foreach (var band in bandLayout.Bands)
|
||||||
{
|
{
|
||||||
if (renderedBands.Contains(band.Id) || band.Columns.Count == 0)
|
if (band.Columns.Count == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -873,6 +786,7 @@ else
|
|||||||
public List<BandDefinition> Bands { get; set; } = new();
|
public List<BandDefinition> Bands { get; set; } = new();
|
||||||
public List<string> ColumnOrder { get; set; } = new();
|
public List<string> ColumnOrder { get; set; } = new();
|
||||||
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
public Dictionary<string, string?> ColumnWidths { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
public GridPersistentLayout? GridLayout { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class BandDefinition
|
private sealed class BandDefinition
|
||||||
@@ -934,4 +848,16 @@ 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 bool gridLayoutApplied;
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (!gridLayoutApplied && gridRef != null && bandLayout.GridLayout != null)
|
||||||
|
{
|
||||||
|
gridRef.LoadLayout(bandLayout.GridLayout);
|
||||||
|
gridLayoutApplied = true;
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user