diff --git a/AyCode.Blazor.Components/Components/Grids/MgGridBase.cs b/AyCode.Blazor.Components/Components/Grids/MgGridBase.cs index e033bea..91572b6 100644 --- a/AyCode.Blazor.Components/Components/Grids/MgGridBase.cs +++ b/AyCode.Blazor.Components/Components/Grids/MgGridBase.cs @@ -53,6 +53,16 @@ public interface IMgGridBase : IGrid /// InfoPanel instance for displaying row details (from wrapper) /// IInfoPanelBase? InfoPanelInstance { get; } + + /// + /// Whether the grid/wrapper is currently in fullscreen mode + /// + bool IsFullscreen { get; } + + /// + /// Toggles fullscreen mode for the grid (or wrapper if available) + /// + void ToggleFullscreen(); } public abstract class MgGridBase : DxGrid, IMgGridBase, IAsyncDisposable @@ -110,6 +120,27 @@ public abstract class MgGridBase + public bool IsFullscreen => GridWrapper?.IsFullscreen ?? _isStandaloneFullscreen; + + private bool _isStandaloneFullscreen; + + /// + public void ToggleFullscreen() + { + if (GridWrapper != null) + { + // Ha van wrapper, azt váltjuk fullscreen-be + GridWrapper.ToggleFullscreen(); + } + else + { + // Ha nincs wrapper, saját fullscreen állapotot használunk + _isStandaloneFullscreen = !_isStandaloneFullscreen; + InvokeAsync(StateHasChanged); + } + } + public MgGridBase() : base() { } @@ -123,7 +154,38 @@ public abstract class MgGridBase { - base.BuildRenderTree(contentBuilder); + if (_isStandaloneFullscreen && GridWrapper == null) + { + // Standalone fullscreen mode - wrap in DxWindow + contentBuilder.OpenComponent(0); + contentBuilder.AddAttribute(1, "Visible", true); + contentBuilder.AddAttribute(2, "VisibleChanged", EventCallback.Factory.Create(this, visible => + { + if (!visible) + { + _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(); + } + else + { + base.BuildRenderTree(contentBuilder); + } })); builder.CloseComponent(); } diff --git a/AyCode.Blazor.Components/Components/Grids/MgGridToolbarTemplate.razor b/AyCode.Blazor.Components/Components/Grids/MgGridToolbarTemplate.razor index f9f3115..f358824 100644 --- a/AyCode.Blazor.Components/Components/Grids/MgGridToolbarTemplate.razor +++ b/AyCode.Blazor.Components/Components/Grids/MgGridToolbarTemplate.razor @@ -23,7 +23,7 @@ - + @ToolbarItemsExtended } @@ -55,6 +55,21 @@ /// private bool HasFocusedRow => Grid?.GetFocusedRowIndex() >= 0; + /// + /// Whether the grid is currently in fullscreen mode + /// + private bool IsFullscreenMode => Grid?.IsFullscreen ?? false; + + /// + /// Button text for fullscreen toggle + /// + private string FullscreenButtonText => IsFullscreenMode ? "Exit Fullscreen" : "Fullscreen"; + + /// + /// Icon class for fullscreen toggle button + /// + private string FullscreenIconCssClass => IsFullscreenMode ? "grid-fullscreen-exit" : "grid-fullscreen"; + protected override void OnInitialized() { } @@ -112,6 +127,11 @@ Grid.ShowColumnChooser(); } + void Fullscreen_Click() + { + Grid.ToggleFullscreen(); + } + async Task ExportXlsxItem_Click() { await Grid.ExportToXlsxAsync(ExportFileName); diff --git a/AyCode.Blazor.Components/Components/Grids/MgGridWithInfoPanel.razor b/AyCode.Blazor.Components/Components/Grids/MgGridWithInfoPanel.razor index 80155bc..5f4f9ee 100644 --- a/AyCode.Blazor.Components/Components/Grids/MgGridWithInfoPanel.razor +++ b/AyCode.Blazor.Components/Components/Grids/MgGridWithInfoPanel.razor @@ -1,34 +1,35 @@ @using DevExpress.Blazor - @if (ShowInfoPanel) + @if (_isFullscreen) { - - - - @GridContent - - - @if (ChildContent != null) - { - @ChildContent - } - else - { - - } - - - + + +
+ @RenderMainContent() +
+
+
} else { - @GridContent + @RenderMainContent() }
@code { private IInfoPanelBase? _infoPanelInstance; + private IMgGridBase? _currentGrid; + private bool _isFullscreen; /// /// The grid content to display in the left pane @@ -55,6 +56,11 @@ [Parameter] public bool ShowInfoPanel { get; set; } = true; + /// + /// Whether the wrapper is currently in fullscreen mode + /// + public bool IsFullscreen => _isFullscreen; + /// /// Gets or sets the InfoPanel instance for grid-InfoPanel communication /// @@ -71,4 +77,67 @@ { _infoPanelInstance = infoPanel; } + + /// + /// Registers the grid instance (called by MgGridBase) + /// + public void RegisterGrid(IMgGridBase grid) + { + _currentGrid = grid; + } + + /// + /// Toggles fullscreen mode + /// + public void ToggleFullscreen() + { + _isFullscreen = !_isFullscreen; + StateHasChanged(); + } + + /// + /// Enters fullscreen mode + /// + public void EnterFullscreen() + { + _isFullscreen = true; + StateHasChanged(); + } + + /// + /// Exits fullscreen mode + /// + public void ExitFullscreen() + { + _isFullscreen = false; + StateHasChanged(); + } + + private RenderFragment RenderMainContent() => __builder => + { + if (ShowInfoPanel) + { + + + + @GridContent + + + @if (ChildContent != null) + { + @ChildContent + } + else + { + + } + + + + } + else + { + @GridContent + } + }; } diff --git a/AyCode.Blazor.Components/wwwroot/css/mg-grid-info-panel.css b/AyCode.Blazor.Components/wwwroot/css/mg-grid-info-panel.css index 2c15dfa..49c2722 100644 --- a/AyCode.Blazor.Components/wwwroot/css/mg-grid-info-panel.css +++ b/AyCode.Blazor.Components/wwwroot/css/mg-grid-info-panel.css @@ -115,3 +115,47 @@ .mg-info-panel-pane { background-color: var(--dxbl-bg-secondary, #f8f9fa); } + +/* Fullscreen window styling */ +.mg-fullscreen-window { + position: fixed !important; + top: 0 !important; + left: 0 !important; + margin: 0 !important; + border-radius: 0 !important; +} + +.mg-fullscreen-window .dxbl-window-body { + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.mg-fullscreen-content { + flex: 1; + height: 100%; + overflow: hidden; + display: flex; + flex-direction: column; +} + +.mg-fullscreen-content .mg-grid-with-info-panel { + flex: 1; + height: 100%; +} + +.mg-fullscreen-content .dxbl-grid { + height: 100% !important; +} + +/* Fullscreen icon classes */ +.grid-fullscreen::before { + content: "\e90c"; + font-family: 'devextreme-icons'; +} + +.grid-fullscreen-exit::before { + content: "\e90d"; + font-family: 'devextreme-icons'; +}