Add fullscreen grid support and PDF preview in info panel
- Added fullscreen mode to grid and info panel components, including toolbar toggle and fullscreen styling. - Introduced embedded PDF viewing in the info panel using PDF.js and a custom JavaScript viewer. - Updated interfaces, CSS, and toolbar templates to support new features. - Added new PDF asset (2_BANK FRA.pdf) for document preview. - Minor: Added local settings for Bash permission, fixed text encoding, and improved info panel table layout. - No code changes in other referenced PDF files; added for informational or asset purposes only.
This commit is contained in:
parent
5255917210
commit
4c86914884
|
|
@ -53,6 +53,16 @@ public interface IMgGridBase : IGrid
|
|||
/// InfoPanel instance for displaying row details (from wrapper)
|
||||
/// </summary>
|
||||
IInfoPanelBase? InfoPanelInstance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the grid/wrapper is currently in fullscreen mode
|
||||
/// </summary>
|
||||
bool IsFullscreen { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Toggles fullscreen mode for the grid (or wrapper if available)
|
||||
/// </summary>
|
||||
void ToggleFullscreen();
|
||||
}
|
||||
|
||||
public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClient> : DxGrid, IMgGridBase, IAsyncDisposable
|
||||
|
|
@ -110,6 +120,27 @@ public abstract class MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClie
|
|||
set { /* Set through wrapper */ }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsFullscreen => GridWrapper?.IsFullscreen ?? _isStandaloneFullscreen;
|
||||
|
||||
private bool _isStandaloneFullscreen;
|
||||
|
||||
/// <inheritdoc />
|
||||
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<TSignalRDataSource, TDataItem, TId, TLoggerClie
|
|||
builder.AddAttribute(seq++, "Value", (IMgGridBase)this);
|
||||
builder.AddAttribute(seq++, "ChildContent", (RenderFragment)(contentBuilder =>
|
||||
{
|
||||
base.BuildRenderTree(contentBuilder);
|
||||
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 =>
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</Items>
|
||||
</DxToolbarItem>
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : "Reload data")" BeginGroup="true" Click="ReloadData_Click" IconCssClass="grid-refresh" Enabled="@(!IsSyncing && !_isReloadInProgress && !IsEditing)" />
|
||||
<DxToolbarItem BeginGroup="true"></DxToolbarItem>
|
||||
<DxToolbarItem Text="@(ShowOnlyIcon ? "" : FullscreenButtonText)" Click="Fullscreen_Click" IconCssClass="@FullscreenIconCssClass" Enabled="@(!IsEditing)" />
|
||||
@ToolbarItemsExtended
|
||||
}
|
||||
</MgGridToolbarBase>
|
||||
|
|
@ -55,6 +55,21 @@
|
|||
/// </summary>
|
||||
private bool HasFocusedRow => Grid?.GetFocusedRowIndex() >= 0;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the grid is currently in fullscreen mode
|
||||
/// </summary>
|
||||
private bool IsFullscreenMode => Grid?.IsFullscreen ?? false;
|
||||
|
||||
/// <summary>
|
||||
/// Button text for fullscreen toggle
|
||||
/// </summary>
|
||||
private string FullscreenButtonText => IsFullscreenMode ? "Exit Fullscreen" : "Fullscreen";
|
||||
|
||||
/// <summary>
|
||||
/// Icon class for fullscreen toggle button
|
||||
/// </summary>
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,34 +1,35 @@
|
|||
@using DevExpress.Blazor
|
||||
|
||||
<CascadingValue Value="this">
|
||||
@if (ShowInfoPanel)
|
||||
@if (_isFullscreen)
|
||||
{
|
||||
<DxSplitter Width="100%" CssClass="mg-grid-with-info-panel" Orientation="Orientation.Horizontal">
|
||||
<Panes>
|
||||
<DxSplitterPane>
|
||||
@GridContent
|
||||
</DxSplitterPane>
|
||||
<DxSplitterPane Size="@InfoPanelSize" MinSize="0px" MaxSize="100%" AllowCollapse="true" CssClass="mg-info-panel-pane">
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else
|
||||
{
|
||||
<MgGridInfoPanel />
|
||||
}
|
||||
</DxSplitterPane>
|
||||
</Panes>
|
||||
</DxSplitter>
|
||||
<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>
|
||||
}
|
||||
else
|
||||
{
|
||||
@GridContent
|
||||
@RenderMainContent()
|
||||
}
|
||||
</CascadingValue>
|
||||
|
||||
@code {
|
||||
private IInfoPanelBase? _infoPanelInstance;
|
||||
private IMgGridBase? _currentGrid;
|
||||
private bool _isFullscreen;
|
||||
|
||||
/// <summary>
|
||||
/// The grid content to display in the left pane
|
||||
|
|
@ -55,6 +56,11 @@
|
|||
[Parameter]
|
||||
public bool ShowInfoPanel { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the wrapper is currently in fullscreen mode
|
||||
/// </summary>
|
||||
public bool IsFullscreen => _isFullscreen;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the InfoPanel instance for grid-InfoPanel communication
|
||||
/// </summary>
|
||||
|
|
@ -71,4 +77,67 @@
|
|||
{
|
||||
_infoPanelInstance = infoPanel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the grid instance (called by MgGridBase)
|
||||
/// </summary>
|
||||
public void RegisterGrid(IMgGridBase grid)
|
||||
{
|
||||
_currentGrid = grid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles fullscreen mode
|
||||
/// </summary>
|
||||
public void ToggleFullscreen()
|
||||
{
|
||||
_isFullscreen = !_isFullscreen;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enters fullscreen mode
|
||||
/// </summary>
|
||||
public void EnterFullscreen()
|
||||
{
|
||||
_isFullscreen = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exits fullscreen mode
|
||||
/// </summary>
|
||||
public void ExitFullscreen()
|
||||
{
|
||||
_isFullscreen = false;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private RenderFragment RenderMainContent() => __builder =>
|
||||
{
|
||||
if (ShowInfoPanel)
|
||||
{
|
||||
<DxSplitter Width="100%" Height="@(_isFullscreen ? "100%" : null)" CssClass="mg-grid-with-info-panel" Orientation="Orientation.Horizontal">
|
||||
<Panes>
|
||||
<DxSplitterPane>
|
||||
@GridContent
|
||||
</DxSplitterPane>
|
||||
<DxSplitterPane Size="@InfoPanelSize" MinSize="0px" MaxSize="100%" AllowCollapse="true" CssClass="mg-info-panel-pane">
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else
|
||||
{
|
||||
<MgGridInfoPanel />
|
||||
}
|
||||
</DxSplitterPane>
|
||||
</Panes>
|
||||
</DxSplitter>
|
||||
}
|
||||
else
|
||||
{
|
||||
@GridContent
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue