Refactor fullscreen grid UI; add serializer diagnostics/tests

- Replaced DxWindow with custom Bootstrap 5 fullscreen overlay for grid components, improving fullscreen UX and styling.
- Added new CSS for fullscreen overlay, header, and body; retained legacy DxWindow styles for compatibility.
- Introduced SignalRSerializerDiagnosticLog flag to control binary serializer diagnostics at runtime.
- Enabled diagnostics in DevAdminSignalRHub, FruitBankSignalRClient, and Program.cs based on the new flag.
- Updated OrderClientTests to use GetStockTakings(false).
- Added StockTakingSerializerTests for binary serialization/deserialization validation and debugging.
This commit is contained in:
Loretta 2025-12-20 08:40:03 +01:00
parent 017eb16c4b
commit 15776ca537
3 changed files with 96 additions and 40 deletions

View File

@ -156,31 +156,39 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
{ {
if (_isStandaloneFullscreen && GridWrapper == null) if (_isStandaloneFullscreen && GridWrapper == null)
{ {
// Standalone fullscreen mode - wrap in DxWindow // Standalone fullscreen mode - Bootstrap 5 fullscreen overlay
contentBuilder.OpenComponent<DxWindow>(0); contentBuilder.OpenElement(0, "div");
contentBuilder.AddAttribute(1, "Visible", true); contentBuilder.AddAttribute(1, "class", "mg-fullscreen-overlay");
contentBuilder.AddAttribute(2, "VisibleChanged", EventCallback.Factory.Create<bool>(this, visible =>
{ // Header
if (!visible) contentBuilder.OpenElement(2, "div");
contentBuilder.AddAttribute(3, "class", "mg-fullscreen-header");
contentBuilder.OpenElement(4, "span");
contentBuilder.AddAttribute(5, "class", "mg-fullscreen-title");
contentBuilder.AddContent(6, Caption);
contentBuilder.CloseElement(); // span
contentBuilder.OpenElement(7, "button");
contentBuilder.AddAttribute(8, "type", "button");
contentBuilder.AddAttribute(9, "class", "btn-close btn-close-white");
contentBuilder.AddAttribute(10, "aria-label", "Close");
contentBuilder.AddAttribute(11, "onclick", EventCallback.Factory.Create<Microsoft.AspNetCore.Components.Web.MouseEventArgs>(this, () =>
{ {
_isStandaloneFullscreen = false; _isStandaloneFullscreen = false;
InvokeAsync(StateHasChanged); InvokeAsync(StateHasChanged);
}
})); }));
contentBuilder.AddAttribute(3, "ShowHeader", true); contentBuilder.CloseElement(); // button
contentBuilder.AddAttribute(4, "HeaderText", Caption);
contentBuilder.AddAttribute(5, "ShowCloseButton", true); contentBuilder.CloseElement(); // header div
contentBuilder.AddAttribute(6, "CloseOnEscape", true);
contentBuilder.AddAttribute(7, "ShowFooter", false); // Body
contentBuilder.AddAttribute(8, "Scrollable", true); contentBuilder.OpenElement(12, "div");
contentBuilder.AddAttribute(9, "Width", "100vw"); contentBuilder.AddAttribute(13, "class", "mg-fullscreen-body");
contentBuilder.AddAttribute(10, "Height", "100vh"); base.BuildRenderTree(contentBuilder);
contentBuilder.AddAttribute(11, "CssClass", "mg-fullscreen-window"); contentBuilder.CloseElement(); // body div
contentBuilder.AddAttribute(12, "ChildContent", (RenderFragment)(windowBuilder =>
{ contentBuilder.CloseElement(); // overlay div
base.BuildRenderTree(windowBuilder);
}));
contentBuilder.CloseComponent();
} }
else else
{ {

View File

@ -3,22 +3,15 @@
<CascadingValue Value="this"> <CascadingValue Value="this">
@if (_isFullscreen) @if (_isFullscreen)
{ {
<DxWindow @bind-Visible="_isFullscreen" <div class="mg-fullscreen-overlay">
ShowHeader="true" <div class="mg-fullscreen-header">
HeaderText="@(_currentGrid?.Caption ?? "Grid")" <span class="mg-fullscreen-title">@(_currentGrid?.Caption ?? "Grid")</span>
ShowCloseButton="true" <button type="button" class="btn-close btn-close-white" aria-label="Close" @onclick="ExitFullscreen"></button>
CloseOnEscape="true" </div>
ShowFooter="false" <div class="mg-fullscreen-body">
Scrollable="false"
Width="100vw"
Height="100vh"
CssClass="mg-fullscreen-window">
<BodyTemplate>
<div class="mg-fullscreen-content">
@RenderMainContent() @RenderMainContent()
</div> </div>
</BodyTemplate> </div>
</DxWindow>
} }
else else
{ {

View File

@ -168,7 +168,62 @@
background-color: var(--dxbl-bg-secondary); background-color: var(--dxbl-bg-secondary);
} }
/* Fullscreen window styling */ /* Fullscreen overlay styling (Bootstrap 5 based) */
.mg-fullscreen-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100vw;
height: 100vh;
z-index: 1050;
background-color: var(--dxbl-bg, #fff);
display: flex;
flex-direction: column;
overflow: hidden;
}
.mg-fullscreen-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1rem;
background-color: var(--dxbl-primary, #0d6efd);
color: #fff;
border-bottom: 1px solid var(--dxbl-border-color);
flex-shrink: 0;
}
.mg-fullscreen-title {
font-size: 1.1rem;
font-weight: 600;
margin: 0;
}
.mg-fullscreen-header .btn-close-white {
filter: brightness(0) invert(1);
opacity: 0.8;
}
.mg-fullscreen-header .btn-close-white:hover {
opacity: 1;
}
.mg-fullscreen-body {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.mg-fullscreen-body .mg-grid-with-info-panel,
.mg-fullscreen-body .dxbl-grid {
flex: 1;
height: 100%;
}
/* Legacy DxWindow styling (kept for backwards compatibility) */
.mg-fullscreen-window { .mg-fullscreen-window {
position: fixed !important; position: fixed !important;
top: 0 !important; top: 0 !important;