Add collapsible band editor to grid components

Introduce a toggleable "Band-Layout konfigurieren" section in CatalogsGrid.razor and MassDataGrid.razor, allowing users to expand or collapse the band editor UI. Added bandEditorExpanded state to control visibility. Updated CSS to style the new toggle button and its expanded/collapsed states, improving usability and reducing UI clutter.
This commit is contained in:
OlgunR
2026-03-27 09:46:15 +01:00
parent 64fb76b9e6
commit 6101561e72
3 changed files with 107 additions and 74 deletions

View File

@@ -25,6 +25,13 @@ else if (items.Count == 0)
else
{
<div class="band-editor">
<button class="band-editor-toggle" @onclick="() => bandEditorExpanded = !bandEditorExpanded">
<span class="band-editor-toggle-icon @(bandEditorExpanded ? "expanded" : "")">&#9658;</span>
<span>Band-Layout konfigurieren</span>
</button>
@if (bandEditorExpanded)
{
<div class="band-editor-body">
<div class="band-controls">
<DxButton Text="Band hinzufügen" Click="AddBand" />
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
@@ -53,6 +60,8 @@ else
}
</DxFormLayout>
</div>
}
</div>
<div class="grid-section">
<DxGrid Data="@items"
@@ -150,6 +159,7 @@ else
private List<BandOption> bandOptions = new();
private Dictionary<string, ColumnDefinition> columnLookup = new();
private bool gridLayoutApplied;
private bool bandEditorExpanded;
private List<ColumnDefinition> columnDefinitions = new()
{

View File

@@ -37,6 +37,13 @@ else
</div>
<div class="band-editor">
<button class="band-editor-toggle" @onclick="() => bandEditorExpanded = !bandEditorExpanded">
<span class="band-editor-toggle-icon @(bandEditorExpanded ? "expanded" : "")">&#9658;</span>
<span>Band-Layout konfigurieren</span>
</button>
@if (bandEditorExpanded)
{
<div class="band-editor-body">
<div class="band-controls">
<DxButton Text="Band hinzufügen" Click="AddBand" />
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
@@ -65,6 +72,8 @@ else
}
</DxFormLayout>
</div>
}
</div>
<div class="grid-section">
<DxGrid Data="@items"
@@ -178,6 +187,7 @@ else
private List<BandOption> bandOptions = new();
private Dictionary<string, ColumnDefinition> columnLookup = new();
private bool gridLayoutApplied;
private bool bandEditorExpanded;
private List<ColumnDefinition> columnDefinitions = new()
{
@@ -281,7 +291,6 @@ else
{
if (string.IsNullOrWhiteSpace(layoutUser))
return;
try
{
CaptureColumnLayoutFromGrid();
@@ -299,41 +308,31 @@ else
{
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;
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))
@@ -407,15 +406,12 @@ else
builder.OpenComponent<DxGridCommandColumn>(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<DxGridBandColumn>(seq++);
builder.AddAttribute(seq++, "Caption", band.Caption);
builder.AddAttribute(seq++, "Columns", (RenderFragment)(bandBuilder =>
@@ -458,14 +454,12 @@ else
private void OnEditFieldChanged(object? sender, FieldChangedEventArgs e)
{
if (validationMessageStore == null || editContext == null) return;
if (e.FieldIdentifier.FieldName == nameof(MassDataEditModel.UpdateProcedure))
{
validationMessageStore.Clear();
editContext.NotifyValidationStateChanged();
return;
}
if (e.FieldIdentifier.FieldName == nameof(MassDataEditModel.CustomerName))
{
validationMessageStore.Clear(new FieldIdentifier(editContext.Model, nameof(MassDataEditModel.CustomerName)));
@@ -483,7 +477,6 @@ else
SetPopupHeaderText(true);
return;
}
var item = (MassDataReadDto)e.DataItem;
e.EditModel = new MassDataEditModel
{
@@ -505,7 +498,6 @@ else
infoMessage = null;
validationMessageStore?.Clear();
editContext?.NotifyValidationStateChanged();
var editModel = (MassDataEditModel)e.EditModel;
if (!decimal.TryParse(editModel.AmountText, out var amount))
{
@@ -513,7 +505,6 @@ else
e.Cancel = true;
return;
}
if (editModel.IsNew)
{
var existing = await Api.GetByCustomerNameAsync(editModel.CustomerName);
@@ -524,7 +515,6 @@ else
return;
}
}
var dto = new MassDataWriteDto
{
CustomerName = editModel.CustomerName,
@@ -532,7 +522,6 @@ else
Category = editModel.Category,
StatusFlag = editModel.StatusFlag
};
try
{
var saved = await Api.UpsertAsync(dto);

View File

@@ -11,6 +11,7 @@ html, body {
.app-light {
--band-editor-bg: #f8f9fa;
--band-editor-border: #dee2e6;
--band-toggle-hover-bg: #e9ecef;
}
.app-dark {
@@ -18,6 +19,7 @@ html, body {
color: #f1f1f1;
--band-editor-bg: #2d2d2d;
--band-editor-border: #444444;
--band-toggle-hover-bg: #3a3a3a;
}
a, .btn-link {
@@ -74,15 +76,47 @@ h1:focus {
/* Grid Band-Editor */
.band-editor {
display: flex;
flex-direction: column;
gap: 12px;
padding: 12px;
margin-top: 4px;
margin-bottom: 16px;
border: 1px solid var(--band-editor-border);
border-radius: 4px;
background-color: var(--band-editor-bg);
overflow: hidden;
}
.band-editor-toggle {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 8px 12px;
background: none;
border: none;
cursor: pointer;
font-size: inherit;
color: inherit;
text-align: left;
}
.band-editor-toggle:hover {
background-color: var(--band-toggle-hover-bg);
}
.band-editor-toggle-icon {
font-size: 0.7rem;
transition: transform 0.2s ease;
display: inline-block;
}
.band-editor-toggle-icon.expanded {
transform: rotate(90deg);
}
.band-editor-body {
display: flex;
flex-direction: column;
gap: 12px;
padding: 0 12px 12px 12px;
}
.band-controls {