Compare commits
4 Commits
4ac8e94334
...
d422d841ff
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d422d841ff | ||
|
|
ea1b2ea6e4 | ||
|
|
6101561e72 | ||
|
|
64fb76b9e6 |
@@ -25,33 +25,42 @@ else if (items.Count == 0)
|
||||
else
|
||||
{
|
||||
<div class="band-editor">
|
||||
<div class="band-controls">
|
||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||
<DxButton Text="Layout zurücksetzen" Click="ResetLayoutAsync" />
|
||||
</div>
|
||||
@foreach (var band in bandLayout.Bands)
|
||||
<button class="band-editor-toggle" @onclick="() => bandEditorExpanded = !bandEditorExpanded">
|
||||
<span class="band-editor-toggle-icon @(bandEditorExpanded ? "expanded" : "")">►</span>
|
||||
<span>Layout</span>
|
||||
</button>
|
||||
@if (bandEditorExpanded)
|
||||
{
|
||||
<div class="band-row">
|
||||
<DxTextBox Text="@band.Caption" TextChanged="@(value => UpdateBandCaption(band, value))" />
|
||||
<DxButton Text="Entfernen" Click="@(() => RemoveBand(band))" />
|
||||
<div class="band-editor-body">
|
||||
<div class="band-controls">
|
||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||
<DxButton Text="Layout zurücksetzen" Click="ResetLayoutAsync" />
|
||||
</div>
|
||||
@foreach (var band in bandLayout.Bands)
|
||||
{
|
||||
<div class="band-row">
|
||||
<DxTextBox Text="@band.Caption" TextChanged="@(value => UpdateBandCaption(band, value))" />
|
||||
<DxButton Text="Entfernen" Click="@(() => RemoveBand(band))" />
|
||||
</div>
|
||||
}
|
||||
<DxFormLayout CssClass="band-columns" ColCount="2">
|
||||
@foreach (var column in columnDefinitions)
|
||||
{
|
||||
<DxFormLayoutItem Caption="@column.Caption">
|
||||
<DxComboBox Data="@bandOptions"
|
||||
TData="BandOption"
|
||||
TValue="string"
|
||||
TextFieldName="Caption"
|
||||
ValueFieldName="Id"
|
||||
Value="@GetColumnBand(column.FieldName)"
|
||||
ValueChanged="@(value => UpdateColumnBand(column.FieldName, value))"
|
||||
Width="100%" />
|
||||
</DxFormLayoutItem>
|
||||
}
|
||||
</DxFormLayout>
|
||||
</div>
|
||||
}
|
||||
<DxFormLayout CssClass="band-columns" ColCount="2">
|
||||
@foreach (var column in columnDefinitions)
|
||||
{
|
||||
<DxFormLayoutItem Caption="@column.Caption">
|
||||
<DxComboBox Data="@bandOptions"
|
||||
TData="BandOption"
|
||||
TValue="string"
|
||||
TextFieldName="Caption"
|
||||
ValueFieldName="Id"
|
||||
Value="@GetColumnBand(column.FieldName)"
|
||||
ValueChanged="@(value => UpdateColumnBand(column.FieldName, value))"
|
||||
Width="100%" />
|
||||
</DxFormLayoutItem>
|
||||
}
|
||||
</DxFormLayout>
|
||||
</div>
|
||||
|
||||
<div class="grid-section">
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -24,6 +24,46 @@ 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" : "")">►</span>
|
||||
<span>Layout</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" />
|
||||
<DxButton Text="Layout zurücksetzen" Click="ResetLayoutAsync" />
|
||||
</div>
|
||||
@foreach (var band in bandLayout.Bands)
|
||||
{
|
||||
<div class="band-row">
|
||||
<DxTextBox Text="@band.Caption" TextChanged="@(value => UpdateBandCaption(band, value))" />
|
||||
<DxButton Text="Entfernen" Click="@(() => RemoveBand(band))" />
|
||||
</div>
|
||||
}
|
||||
<DxFormLayout CssClass="band-columns" ColCount="2">
|
||||
@foreach (var column in columnDefinitions)
|
||||
{
|
||||
<DxFormLayoutItem Caption="@column.Caption">
|
||||
<DxComboBox Data="@bandOptions"
|
||||
TData="BandOption"
|
||||
TValue="string"
|
||||
TextFieldName="Caption"
|
||||
ValueFieldName="Id"
|
||||
Value="@GetColumnBand(column.FieldName)"
|
||||
ValueChanged="@(value => UpdateColumnBand(column.FieldName, value))"
|
||||
Width="100%" />
|
||||
</DxFormLayoutItem>
|
||||
}
|
||||
</DxFormLayout>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="mb-3 page-size-selector">
|
||||
<span class="page-size-label">Datensätze je Seite:</span>
|
||||
<DxComboBox Data="@pageSizeOptions"
|
||||
@@ -36,36 +76,6 @@ else
|
||||
CssClass="page-size-combo" />
|
||||
</div>
|
||||
|
||||
<div class="band-editor">
|
||||
<div class="band-controls">
|
||||
<DxButton Text="Band hinzufügen" Click="AddBand" />
|
||||
<DxButton Text="Layout speichern" Click="SaveLayoutAsync" Enabled="@CanSaveBandLayout" />
|
||||
<DxButton Text="Layout zurücksetzen" Click="ResetLayoutAsync" />
|
||||
</div>
|
||||
@foreach (var band in bandLayout.Bands)
|
||||
{
|
||||
<div class="band-row">
|
||||
<DxTextBox Text="@band.Caption" TextChanged="@(value => UpdateBandCaption(band, value))" />
|
||||
<DxButton Text="Entfernen" Click="@(() => RemoveBand(band))" />
|
||||
</div>
|
||||
}
|
||||
<DxFormLayout CssClass="band-columns" ColCount="2">
|
||||
@foreach (var column in columnDefinitions)
|
||||
{
|
||||
<DxFormLayoutItem Caption="@column.Caption">
|
||||
<DxComboBox Data="@bandOptions"
|
||||
TData="BandOption"
|
||||
TValue="string"
|
||||
TextFieldName="Caption"
|
||||
ValueFieldName="Id"
|
||||
Value="@GetColumnBand(column.FieldName)"
|
||||
ValueChanged="@(value => UpdateColumnBand(column.FieldName, value))"
|
||||
Width="100%" />
|
||||
</DxFormLayoutItem>
|
||||
}
|
||||
</DxFormLayout>
|
||||
</div>
|
||||
|
||||
<div class="grid-section">
|
||||
<DxGrid Data="@items"
|
||||
TItem="MassDataReadDto"
|
||||
@@ -178,6 +188,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 +292,6 @@ else
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(layoutUser))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
CaptureColumnLayoutFromGrid();
|
||||
@@ -299,41 +309,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 +407,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 +455,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 +478,6 @@ else
|
||||
SetPopupHeaderText(true);
|
||||
return;
|
||||
}
|
||||
|
||||
var item = (MassDataReadDto)e.DataItem;
|
||||
e.EditModel = new MassDataEditModel
|
||||
{
|
||||
@@ -505,7 +499,6 @@ else
|
||||
infoMessage = null;
|
||||
validationMessageStore?.Clear();
|
||||
editContext?.NotifyValidationStateChanged();
|
||||
|
||||
var editModel = (MassDataEditModel)e.EditModel;
|
||||
if (!decimal.TryParse(editModel.AmountText, out var amount))
|
||||
{
|
||||
@@ -513,7 +506,6 @@ else
|
||||
e.Cancel = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (editModel.IsNew)
|
||||
{
|
||||
var existing = await Api.GetByCustomerNameAsync(editModel.CustomerName);
|
||||
@@ -524,7 +516,6 @@ else
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var dto = new MassDataWriteDto
|
||||
{
|
||||
CustomerName = editModel.CustomerName,
|
||||
@@ -532,7 +523,6 @@ else
|
||||
Category = editModel.Category,
|
||||
StatusFlag = editModel.StatusFlag
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var saved = await Api.UpsertAsync(dto);
|
||||
|
||||
@@ -7,9 +7,21 @@ html, body {
|
||||
font-size: var(--global-size);
|
||||
}
|
||||
|
||||
/* Theme-Variablen */
|
||||
.app-light {
|
||||
--band-editor-bg: #f8f9fa;
|
||||
--band-editor-border: #dee2e6;
|
||||
--band-toggle-hover-bg: #e9ecef;
|
||||
--grid-stripe-bg: rgba(0, 0, 0, 0.03);
|
||||
}
|
||||
|
||||
.app-dark {
|
||||
background-color: #1b1b1b;
|
||||
color: #f1f1f1;
|
||||
--band-editor-bg: #2d2d2d;
|
||||
--band-editor-border: #444444;
|
||||
--band-toggle-hover-bg: #3a3a3a;
|
||||
--grid-stripe-bg: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
a, .btn-link {
|
||||
@@ -66,15 +78,47 @@ h1:focus {
|
||||
|
||||
/* Grid Band-Editor */
|
||||
.band-editor {
|
||||
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: 12px;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 16px;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 4px;
|
||||
background-color: #f8f9fa;
|
||||
padding: 0 12px 12px 12px;
|
||||
}
|
||||
|
||||
.band-controls {
|
||||
@@ -99,6 +143,11 @@ h1:focus {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Grid Zebra-Striping */
|
||||
dxbl-grid tbody tr:nth-child(even) td {
|
||||
background-color: var(--grid-stripe-bg) !important;
|
||||
}
|
||||
|
||||
/* MassData-spezifisch */
|
||||
.page-size-selector {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user