From 3a14b570efd5598d6f4cd59f123315d3aee03b54 Mon Sep 17 00:00:00 2001 From: Loretta Date: Tue, 23 Dec 2025 11:10:19 +0100 Subject: [PATCH 1/2] Add user layout management to grids with toolbar actions - Introduced separate auto-save and user-save layout storage keys - Added IMgGridBase methods for saving, loading, resetting, and checking user layouts - Updated grid toolbar with "Layout" menu (load, save, reset) and new icons - Improved layout persistence logic and default layout restore - Enabled forced grid re-render on layout reset - Adjusted grid pager and page size defaults - Updated related components to use new storage keys - Fixed minor bugs and set RELEASE log level to Debug --- FruitBank.Common/FruitBankConstClient.cs | 2 +- .../Components/GridProductDtoTemplate.razor | 2 +- .../Components/Grids/FruitBankGridBase.cs | 4 +- .../Grids/Partners/GridPartner.razor | 1 - .../GridShippingDocumentInfoPanel.razor | 26 +++--- .../Components/MgGridBase.cs | 82 +++++++++---------- FruitBankHybrid.Shared/wwwroot/app.css | 52 +++++++++++- 7 files changed, 109 insertions(+), 60 deletions(-) diff --git a/FruitBank.Common/FruitBankConstClient.cs b/FruitBank.Common/FruitBankConstClient.cs index 07bac4e..a90f6ad 100644 --- a/FruitBank.Common/FruitBankConstClient.cs +++ b/FruitBank.Common/FruitBankConstClient.cs @@ -107,7 +107,7 @@ public static class FruitBankConstClient #if RELEASE public static string SystemEmailAddress = "test@touriam.com"; - public static LogLevel DefaultLogLevelClient = LogLevel.Error; + public static LogLevel DefaultLogLevelClient = LogLevel.Debug; #else public static string SystemEmailAddress = "test@touriam.com"; public static LogLevel DefaultLogLevelClient = LogLevel.Detail; diff --git a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor index 707fe77..1f9c506 100644 --- a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor +++ b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor @@ -20,7 +20,7 @@ + Logger="_logger" SignalRClient="FruitBankSignalRClient" Caption="Termék(ek)"> diff --git a/FruitBankHybrid.Shared/Components/Grids/FruitBankGridBase.cs b/FruitBankHybrid.Shared/Components/Grids/FruitBankGridBase.cs index ea901f9..ea94bc7 100644 --- a/FruitBankHybrid.Shared/Components/Grids/FruitBankGridBase.cs +++ b/FruitBankHybrid.Shared/Components/Grids/FruitBankGridBase.cs @@ -73,8 +73,8 @@ public class FruitBankGridBase : MgGridBase diff --git a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor index 7389368..9a0cc4d 100644 --- a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor +++ b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor @@ -23,7 +23,9 @@ *@ - @if (ctx is { IsEditMode: false, DataItem: ShippingDocument doc }) + @if (ctx.DataItem is not ShippingDocument && ctx.DataItem is not ShippingItem) return; + + @if (ctx is { DataItem: ShippingDocument doc, IsEditMode: false }) { @@ -68,16 +70,16 @@
- - -
-
-
} + + +
+
+
@* @@ -108,10 +110,12 @@ private async Task OnDataItemChangedAsync(object? dataItem) { + @if (dataItem is not ShippingDocument && dataItem is not ShippingItem) return; + // Store the PDF to render _randomPdf = _pdfFiles[Random.Shared.Next(_pdfFiles.Length)]; _currentPdfToRender = $"_content/FruitBankHybrid.Shared/uploads/{_randomPdf}"; - + // If MgLazyLoadContent is already visible, render the PDF immediately if (_lazyContentRef is { IsVisible: true }) { diff --git a/FruitBankHybrid.Shared/Components/MgGridBase.cs b/FruitBankHybrid.Shared/Components/MgGridBase.cs index 58ffc80..7bafe0e 100644 --- a/FruitBankHybrid.Shared/Components/MgGridBase.cs +++ b/FruitBankHybrid.Shared/Components/MgGridBase.cs @@ -47,7 +47,9 @@ public class MgGridBase : DxGrid, IMgGridBase /// public bool IsFullscreen => false; - public string LayoutStorageKey { get; } + public string AutomaticLayoutStorageKey => $"{AutoSaveLayoutName}_Master_AutoSave_{LoggedInModel.CustomerDto?.Id ?? 0}"; + + private string UserLayoutStorageKey => AutomaticLayoutStorageKey.Replace("_AutoSave_", "_UserSave_"); /// public void ToggleFullscreen() @@ -141,8 +143,8 @@ public class MgGridBase : DxGrid, IMgGridBase AutoCollapseDetailRow = true; AutoExpandAllGroupRows = false; - PagerVisible = IsMasterGrid; - PageSize = IsMasterGrid ? (SizeMode == DevExpress.Blazor.SizeMode.Small ? 23 : 15) : 50; + PagerVisible = true; //IsMasterGrid; + PageSize = IsMasterGrid ? (SizeMode == DevExpress.Blazor.SizeMode.Small ? 20 : 15) : 10; AllowColumnReorder = true; AllowGroup = IsMasterGrid; @@ -204,12 +206,12 @@ public class MgGridBase : DxGrid, IMgGridBase async Task Grid_LayoutAutoLoading(GridPersistentLayoutEventArgs e) { - e.Layout = await LoadLayoutFromLocalStorageAsync($"{AutoSaveLayoutName}_AutoSave_{LoggedInModel.CustomerDto?.Id ?? 0}"); + e.Layout = await LoadLayoutFromLocalStorageAsync(AutomaticLayoutStorageKey); } private async Task Grid_LayoutAutoSaving(GridPersistentLayoutEventArgs e) { - await SaveLayoutToLocalStorageAsync(e.Layout, $"{AutoSaveLayoutName}_AutoSave_{LoggedInModel.CustomerDto?.Id ?? 0}"); + await SaveLayoutToLocalStorageAsync(e.Layout, AutomaticLayoutStorageKey); } async Task LoadLayoutFromLocalStorageAsync(string localStorageKey) @@ -227,6 +229,7 @@ public class MgGridBase : DxGrid, IMgGridBase return null; } + async Task SaveLayoutToLocalStorageAsync(GridPersistentLayout layout, string localStorageKey) { try @@ -243,54 +246,49 @@ public class MgGridBase : DxGrid, IMgGridBase { try { - await JSRuntime.InvokeVoidAsync("localStorage.removeItem", AutoSaveLayoutName); + await JSRuntime.InvokeVoidAsync("localStorage.removeItem", AutomaticLayoutStorageKey); } catch { // Mute exceptions for the server prerender stage } } - async Task ReloadPageButton_ClickAsync() + + /// + public async Task SaveUserLayoutAsync() { - await JSRuntime.InvokeVoidAsync("location.reload"); + var layout = SaveLayout(); + await SaveLayoutToLocalStorageAsync(layout, UserLayoutStorageKey); } - async Task ResetLayoutButton_ClickAsync() + + /// + public async Task LoadUserLayoutAsync() + { + var layout = await LoadLayoutFromLocalStorageAsync(UserLayoutStorageKey); + if (layout != null) + { + LoadLayout(layout); + } + } + + /// + public async Task ResetLayoutAsync() { await RemoveLayoutFromLocalStorageAsync(); await JSRuntime.InvokeVoidAsync("location.reload"); } - //public RenderFragment AddCommandColumn() - //{ - // RenderFragment columns = b => - // { - // if (!IsMasterGrid) - // { - // b.OpenComponent(0, typeof(DxGridCommandColumn)); - // b.CloseComponent(); - // } - // }; - // this.Columns.ApplyChain(x) = AddCommandColumn(); - - // return columns; - //} - - //private RenderFragment BuildColumnsGrid() - //{ - // PropertyInfo[] props = DataSource.FirstOrDefault().GetType().GetProperties(); - // RenderFragment columns = b => - // { - // foreach (var prop in props) - // { - // if (prop.PropertyType == typeof(string)) - // { - - // b.OpenComponent(0, typeof(DxGridDataColumn)); - // b.AddAttribute(0, "FieldName", prop.Name); - // b.CloseComponent(); - // } - // } - // }; - // return columns; - //} + /// + public async Task HasUserLayoutAsync() + { + try + { + var value = await JSRuntime.InvokeAsync("localStorage.getItem", UserLayoutStorageKey); + return !string.IsNullOrWhiteSpace(value); + } + catch + { + return false; + } + } } \ No newline at end of file diff --git a/FruitBankHybrid.Shared/wwwroot/app.css b/FruitBankHybrid.Shared/wwwroot/app.css index 1638794..1bbebda 100644 --- a/FruitBankHybrid.Shared/wwwroot/app.css +++ b/FruitBankHybrid.Shared/wwwroot/app.css @@ -161,10 +161,16 @@ h1:focus { .grid-chevron-up, .grid-chevron-down, .grid-column-chooser, +.grid-layout, +.grid-layout-load, +.grid-layout-save, +.grid-layout-reset, .grid-export, .grid-export-xlsx, .grid-export-pdf, -.grid-refresh { +.grid-refresh, +.grid-fullscreen, +.grid-fullscreen-exit { display: inline-flex; align-items: center; justify-content: center; @@ -178,10 +184,16 @@ h1:focus { .grid-chevron-up::before, .grid-chevron-down::before, .grid-column-chooser::before, + .grid-layout::before, + .grid-layout-load::before, + .grid-layout-save::before, + .grid-layout-reset::before, .grid-export::before, .grid-export-xlsx::before, .grid-export-pdf::before, - .grid-refresh::before { + .grid-refresh::before, + .grid-fullscreen::before, + .grid-fullscreen-exit::before { content: ""; display: inline-block; width: 1.25rem; @@ -268,6 +280,42 @@ h1:focus { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='23 4 23 10 17 10'/%3E%3Cpolyline points='1 20 1 14 7 14'/%3E%3Cpath d='M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15'/%3E%3C/svg%3E"); } + /* Layout icon (sliders/settings) */ + .grid-layout::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cline x1='4' y1='21' x2='4' y2='14'/%3E%3Cline x1='4' y1='10' x2='4' y2='3'/%3E%3Cline x1='12' y1='21' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12' y2='3'/%3E%3Cline x1='20' y1='21' x2='20' y2='16'/%3E%3Cline x1='20' y1='12' x2='20' y2='3'/%3E%3Cline x1='1' y1='14' x2='7' y2='14'/%3E%3Cline x1='9' y1='8' x2='15' y2='8'/%3E%3Cline x1='17' y1='16' x2='23' y2='16'/%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cline x1='4' y1='21' x2='4' y2='14'/%3E%3Cline x1='4' y1='10' x2='4' y2='3'/%3E%3Cline x1='12' y1='21' x2='12' y2='12'/%3E%3Cline x1='12' y1='8' x2='12' y2='3'/%3E%3Cline x1='20' y1='21' x2='20' y2='16'/%3E%3Cline x1='20' y1='12' x2='20' y2='3'/%3E%3Cline x1='1' y1='14' x2='7' y2='14'/%3E%3Cline x1='9' y1='8' x2='15' y2='8'/%3E%3Cline x1='17' y1='16' x2='23' y2='16'/%3E%3C/svg%3E"); + } + + /* Layout Load icon (folder open) */ + .grid-layout-load::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z'/%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z'/%3E%3C/svg%3E"); + } + + /* Layout Save icon (save/floppy) */ + .grid-layout-save::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z'/%3E%3Cpolyline points='17 21 17 13 7 13 7 21'/%3E%3Cpolyline points='7 3 7 8 15 8'/%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z'/%3E%3Cpolyline points='17 21 17 13 7 13 7 21'/%3E%3Cpolyline points='7 3 7 8 15 8'/%3E%3C/svg%3E"); + } + + /* Layout Reset icon (rotate-ccw) */ + .grid-layout-reset::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='1 4 1 10 7 10'/%3E%3Cpath d='M3.51 15a9 9 0 1 0 2.13-9.36L1 10'/%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='1 4 1 10 7 10'/%3E%3Cpath d='M3.51 15a9 9 0 1 0 2.13-9.36L1 10'/%3E%3C/svg%3E"); + } + + /* Fullscreen icon (maximize) */ + .grid-fullscreen::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cpolyline points='9 21 3 21 3 15'/%3E%3Cline x1='21' y1='3' x2='14' y2='10'/%3E%3Cline x1='3' y1='21' x2='10' y2='14'/%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cpolyline points='9 21 3 21 3 15'/%3E%3Cline x1='21' y1='3' x2='14' y2='10'/%3E%3Cline x1='3' y1='21' x2='10' y2='14'/%3E%3C/svg%3E"); + } + + /* Fullscreen Exit icon (minimize) */ + .grid-fullscreen-exit::before { + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='4 14 10 14 10 20'/%3E%3Cpolyline points='20 10 14 10 14 4'/%3E%3Cline x1='14' y1='10' x2='21' y2='3'/%3E%3Cline x1='3' y1='21' x2='10' y2='14'/%3E%3C/svg%3E"); + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpolyline points='4 14 10 14 10 20'/%3E%3Cpolyline points='20 10 14 10 14 4'/%3E%3Cline x1='14' y1='10' x2='21' y2='3'/%3E%3Cline x1='3' y1='21' x2='10' y2='14'/%3E%3C/svg%3E"); + } + /* ======================================== MgGrid Splitter with InfoPanel InfoPanel sticky via JavaScript From e61c605b11f3c9e57263cb211411b61dd8864672 Mon Sep 17 00:00:00 2001 From: Loretta Date: Tue, 23 Dec 2025 11:14:32 +0100 Subject: [PATCH 2/2] Update schema compare config, connection, and exclusions Updated connection strings to remove password and add Pooling=False. Added new schema compare settings for pre/post deploy scripts and external models. Upgraded excluded element references to Microsoft.Data.Tools.Schema.Sql v170.0.0.0. Removed dbo.fbOrderItemPallet and dbo.fbShipping from exclusions. --- SqlSchemaCompare_Dev_to_Prod.scmp | 106 +++++++++++++++--------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/SqlSchemaCompare_Dev_to_Prod.scmp b/SqlSchemaCompare_Dev_to_Prod.scmp index 779a84c..96d28c0 100644 --- a/SqlSchemaCompare_Dev_to_Prod.scmp +++ b/SqlSchemaCompare_Dev_to_Prod.scmp @@ -3,12 +3,12 @@ 10 - Data Source=195.26.231.218;Initial Catalog=FruitBank_DEV;Integrated Security=False;Persist Security Info=False;User ID=sa;Password=v6f_?xNfg9N1;Trust Server Certificate=True + Data Source=195.26.231.218;Initial Catalog=FruitBank_DEV;Integrated Security=False;Persist Security Info=False;User ID=sa;Pooling=False;Trust Server Certificate=True - Data Source=195.26.231.218;Initial Catalog=FruitBank_PROD;Integrated Security=False;Persist Security Info=False;User ID=sa;Password=v6f_?xNfg9N1;Trust Server Certificate=True + Data Source=195.26.231.218;Initial Catalog=FruitBank_PROD;Integrated Security=False;Persist Security Info=False;User ID=sa;Pooling=False;Trust Server Certificate=True @@ -175,6 +175,14 @@ IgnorePartitionSchemes False + + IgnorePreDeployScript + False + + + IgnorePostDeployScript + False + IgnoreTablePartitionOptions False @@ -503,6 +511,10 @@ DoNotDropExternalLibraries False + + DoNotDropExternalModels + False + DoNotDropExternalStreamingJobs False @@ -763,6 +775,10 @@ ExcludeExternalLibraries False + + ExcludeExternalModels + False + ExcludeExternalStreamingJobs False @@ -939,169 +955,153 @@ Equals_Objects,Not_Supported_Deploy - + Anata_Development_Team - + TIAM_DEV_log - + TIAM_DEV - + TIAM_DEVRELEASE - + TIAM_DEVRELEASE_log - + dbo Address - + FruitBank_Test_log - + FruitBank_Test - + - - dbo - fbOrderItemPallet - - + dbo DF_fbOrderItemPallet_IsValidated - + dbo fbOrderItemPallet IX_fbOrderItemPallet_OrderItemId - - dbo - fbShipping - - + dbo AvalaraItemClassification - + dbo PK_AvalaraItemClassification - + dbo FacebookPixelConfiguration - + dbo PK_FacebookPixelConfiguration - + dbo GoogleAuthenticatorRecord - + dbo PK_GoogleAuthenticatorRecord - + dbo TaxTransactionLog - + dbo PK_TaxTransactionLog - + dbo vOrder - + SqlView dbo vOrder MS_DiagramPane1 - + SqlView dbo vOrder MS_DiagramPaneCount - + dbo vOrderItem - + SqlView dbo vOrderItem MS_DiagramPane1 - + SqlView dbo vOrderItem MS_DiagramPaneCount - + dbo vOrderItemPallet - + SqlView dbo vOrderItemPallet MS_DiagramPane1 - + SqlView dbo vOrderItemPallet MS_DiagramPaneCount - + dbo vProduct - + SqlView dbo vProduct MS_DiagramPane1 - + SqlView dbo vProduct MS_DiagramPaneCount - + dbo Address - + - - dbo - fbOrderItemPallet - - + dbo DF_fbOrderItemPallet_IsAudited - - dbo - fbShipping - - + dbo DF_fbShipping_IsAllMeasured