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)
{
// Standalone fullscreen mode - wrap in DxWindow
contentBuilder.OpenComponent<DxWindow>(0);
contentBuilder.AddAttribute(1, "Visible", true);
contentBuilder.AddAttribute(2, "VisibleChanged", EventCallback.Factory.Create<bool>(this, visible =>
// Standalone fullscreen mode - Bootstrap 5 fullscreen overlay
contentBuilder.OpenElement(0, "div");
contentBuilder.AddAttribute(1, "class", "mg-fullscreen-overlay");
// Header
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, () =>
{
if (!visible)
{
_isStandaloneFullscreen = false;
InvokeAsync(StateHasChanged);
}
_isStandaloneFullscreen = false;
InvokeAsync(StateHasChanged);
}));
contentBuilder.AddAttribute(3, "ShowHeader", true);
contentBuilder.AddAttribute(4, "HeaderText", Caption);
contentBuilder.AddAttribute(5, "ShowCloseButton", true);
contentBuilder.AddAttribute(6, "CloseOnEscape", true);
contentBuilder.AddAttribute(7, "ShowFooter", false);
contentBuilder.AddAttribute(8, "Scrollable", true);
contentBuilder.AddAttribute(9, "Width", "100vw");
contentBuilder.AddAttribute(10, "Height", "100vh");
contentBuilder.AddAttribute(11, "CssClass", "mg-fullscreen-window");
contentBuilder.AddAttribute(12, "ChildContent", (RenderFragment)(windowBuilder =>
{
base.BuildRenderTree(windowBuilder);
}));
contentBuilder.CloseComponent();
contentBuilder.CloseElement(); // button
contentBuilder.CloseElement(); // header div
// Body
contentBuilder.OpenElement(12, "div");
contentBuilder.AddAttribute(13, "class", "mg-fullscreen-body");
base.BuildRenderTree(contentBuilder);
contentBuilder.CloseElement(); // body div
contentBuilder.CloseElement(); // overlay div
}
else
{

View File

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

View File

@ -168,7 +168,62 @@
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 {
position: fixed !important;
top: 0 !important;