Parcourir la source

OneToMany now no longer does a null query, instead using an internal cache of columns.

Kenric Nugteren il y a 1 an
Parent
commit
e2dcaf6443

+ 203 - 195
inabox.wpf/DigitalForms/DynamicFormLayoutGrid.cs

@@ -10,265 +10,273 @@ using System.Windows.Media.Imaging;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.Scripting;
+using InABox.Wpf;
 using InABox.WPF;
 using Microsoft.Win32;
 using Org.BouncyCastle.Asn1.Mozilla;
 using Syncfusion.Windows.Shared;
 using UnderlineType = InABox.Core.UnderlineType;
 
-namespace InABox.DynamicGrid
+namespace InABox.DynamicGrid;
+
+public abstract class DynamicFormLayoutGrid : DynamicOneToManyGrid<DigitalForm, DigitalFormLayout>
 {
-    public abstract class DynamicFormLayoutGrid : DynamicOneToManyGrid<DigitalForm, DigitalFormLayout>
-    {
-        private readonly BitmapImage design = Wpf.Resources.design.AsBitmapImage();
+    private readonly BitmapImage design = Wpf.Resources.design.AsBitmapImage();
 
-        protected override void Init()
-        {
-            base.Init();
+    protected override void Init()
+    {
+        base.Init();
 
-            ActionColumns.Add(new DynamicImageColumn(DesignImage, DesignClick));
-            //AddButton("Design", PRSDesktop.Resources.design.AsBitmapImage(), DesignClick);
-            HiddenColumns.Add(x => x.Layout);
+        ActionColumns.Add(new DynamicImageColumn(DesignImage, DesignClick));
+        //AddButton("Design", PRSDesktop.Resources.design.AsBitmapImage(), DesignClick);
+        HiddenColumns.Add(x => x.Code);
+        HiddenColumns.Add(x => x.Description);
+        HiddenColumns.Add(x => x.Type);
+        HiddenColumns.Add(x => x.Layout);
 
-            AddButton("Auto Generate", null, AutoGenerate_Click);
-            AddButton("Duplicate", null, Duplicate_Click);
-        }
+        AddButton("Auto Generate", null, AutoGenerate_Click);
+        AddButton("Duplicate", null, Duplicate_Click);
+    }
 
-        protected override void DoReconfigure(FluentList<DynamicGridOption> options)
-        {
-            base.DoReconfigure(options);
+    protected override void DoReconfigure(FluentList<DynamicGridOption> options)
+    {
+        base.DoReconfigure(options);
 
-            options.AddRange(DynamicGridOption.RecordCount, DynamicGridOption.ImportData);
-        }
+        options.AddRange(DynamicGridOption.RecordCount, DynamicGridOption.ImportData);
+    }
 
-        private DFLayout LoadLayoutFromSpreadsheet(ISpreadsheet spreadsheet)
-        {
-            return DigitalFormUtils.LoadLayout(spreadsheet);
-        }
+    private DFLayout LoadLayoutFromSpreadsheet(ISpreadsheet spreadsheet)
+    {
+        return DigitalFormUtils.LoadLayout(spreadsheet);
+    }
 
-        protected override void DoImport()
+    protected override void DoImport()
+    {
+        var dialog = new OpenFileDialog();
+        dialog.Filter = "Excel Spreadsheet (.xlsx)|*.xlsx";
+        if (dialog.ShowDialog() == true)
         {
-            var dialog = new OpenFileDialog();
-            dialog.Filter = "Excel Spreadsheet (.xlsx)|*.xlsx";
-            if (dialog.ShowDialog() == true)
+            try
             {
-                try
+                DFLayout layout;
+                Dictionary<String, String> variablegroups = new Dictionary<string, string>();
+                using (var fs = new FileStream(dialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                 {
-                    DFLayout layout;
-                    Dictionary<String, String> variablegroups = new Dictionary<string, string>();
-                    using (var fs = new FileStream(dialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
-                    {
-                        layout = LoadLayoutFromSpreadsheet(new Spreadsheet(fs));
-                    }
+                    layout = LoadLayoutFromSpreadsheet(new Spreadsheet(fs));
+                }
 
-                    var dfLayout = CreateItem();
-                    dfLayout.Code = Path.GetFileNameWithoutExtension(dialog.FileName).ToUpper();
-                    dfLayout.Description = $"Imported From {Path.GetFileName(dialog.FileName)}";
-                    dfLayout.Layout = layout.SaveLayout();
-                    if(EditItems(new DigitalFormLayout[] { dfLayout }))
+                var dfLayout = CreateItem();
+                dfLayout.Code = Path.GetFileNameWithoutExtension(dialog.FileName).ToUpper();
+                dfLayout.Description = $"Imported From {Path.GetFileName(dialog.FileName)}";
+                dfLayout.Layout = layout.SaveLayout();
+                if(EditItems(new DigitalFormLayout[] { dfLayout }))
+                {
+                    var newVariables = new List<DigitalFormVariable>();
+                    String group = "";
+                    foreach (var element in layout.Elements)
                     {
-                        var newVariables = new List<DigitalFormVariable>();
-                        String group = "";
-                        foreach (var element in layout.Elements)
+                        if (element is DFLayoutHeader header)
                         {
-                            if (element is DFLayoutHeader header)
-                            {
-                                group = header.Header;
-                            }
-                            else if (element is DFLayoutField field)
-                            {
-                                var variable = new DigitalFormVariable();
-                                variable.SetFieldType(field.GetType());
-                                variable.SaveProperties(field.GetProperties());
-                                variable.Group = group;
-                                variable.Code = field.Name;
-                                variable.Description = field.Name;
-                                newVariables.Add(variable);
-                            }
+                            group = header.Header;
+                        }
+                        else if (element is DFLayoutField field)
+                        {
+                            var variable = new DigitalFormVariable();
+                            variable.SetFieldType(field.GetType());
+                            variable.SaveProperties(field.GetProperties());
+                            variable.Group = group;
+                            variable.Code = field.Name;
+                            variable.Description = field.Name;
+                            newVariables.Add(variable);
                         }
-                        if(newVariables.Count > 0)
+                    }
+                    if(newVariables.Count > 0)
+                    {
+                        var variables = GetVariableGrid();
+                        if (variables is not null)
                         {
-                            var variables = GetVariableGrid();
-                            if (variables is not null)
+                            var save = new List<DigitalFormVariable>();
+                            foreach(var newVariable in newVariables)
                             {
-                                var save = new List<DigitalFormVariable>();
-                                foreach(var newVariable in newVariables)
+                                var variable = variables.GetVariable(newVariable.Code);
+                                if(variable is not null)
                                 {
-                                    var variable = variables.GetVariable(newVariable.Code);
-                                    if(variable is not null)
+                                    if(variable.FieldType() != newVariable.FieldType())
                                     {
-                                        if(variable.FieldType() != newVariable.FieldType())
-                                        {
-                                            MessageBox.Show($"Variable [{newVariable.Code}] already exists with a different type!");
-                                        }
-                                    }
-                                    else
-                                    {
-                                        save.Add(newVariable);
+                                        MessageBox.Show($"Variable [{newVariable.Code}] already exists with a different type!");
                                     }
                                 }
-
-                                variables.SaveItems(save.ToArray());
-                                variables.Refresh(false, true);
+                                else
+                                {
+                                    save.Add(newVariable);
+                                }
                             }
-                        }
 
-                        Refresh(false, true);
+                            variables.SaveItems(save.ToArray());
+                            variables.Refresh(false, true);
+                        }
                     }
+
+                    Refresh(false, true);
                 }
-                catch(Exception e)
-                {
-                    Logger.Send(LogType.Error, "", CoreUtils.FormatException(e));
-                    MessageBox.Show($"Error: {e.Message}");
-                }
+            }
+            catch(Exception e)
+            {
+                MessageWindow.ShowError("Something went wrong", e);
             }
         }
+    }
+
+    private bool Duplicate_Click(Button btn, CoreRow[] rows)
+    {
+        if (!rows.Any()) return false;
 
-        private bool Duplicate_Click(Button btn, CoreRow[] rows)
+        SaveItems(rows.Select(x =>
         {
-            if (!rows.Any()) return false;
+            var layout = x.ToObject<DigitalFormLayout>();
 
-            SaveItems(rows.Select(x =>
-            {
-                var layout = x.ToObject<DigitalFormLayout>();
-                layout.ID = Guid.Empty;
-                return layout;
-            }).ToArray());
-            return true;
-        }
+            var newLayout = CreateItem();
+            newLayout.Code = layout.Code;
+            newLayout.Description = layout.Description;
+            newLayout.Type = layout.Type;
+            newLayout.Layout = layout.Layout;
 
-        private bool AutoGenerate_Click(Button btn, CoreRow[] rows)
-        {
-            var menu = new ContextMenu();
+            return newLayout;
+        }).ToArray());
+        return true;
+    }
 
-            menu.AddItem("Desktop Layout", null, AddDesktop_Click);
-            menu.AddItem("Mobile Layout", null, AddMobile_Click);
+    private bool AutoGenerate_Click(Button btn, CoreRow[] rows)
+    {
+        var menu = new ContextMenu();
 
-            menu.IsOpen = true;
+        menu.AddItem("Desktop Layout", null, AddDesktop_Click);
+        menu.AddItem("Mobile Layout", null, AddMobile_Click);
 
-            return false;
-        }
+        menu.IsOpen = true;
 
-        private BitmapImage? DesignImage(CoreRow? row)
-        {
-            return row != null ? design : null;
-        }
+        return false;
+    }
 
-        private void AddMobile_Click()
-        {
-            var item = CreateItem();
+    private BitmapImage? DesignImage(CoreRow? row)
+    {
+        return row != null ? design : null;
+    }
 
-            item.Layout = DFLayout.GenerateAutoMobileLayout(GetVariables()).SaveLayout();
-            item.Type = DFLayoutType.Mobile;
+    private void AddMobile_Click()
+    {
+        var item = CreateItem();
 
-            if (EditItems(new[] { item }))
-            {
-                SaveItem(item);
-                Refresh(false, true);
-                DoChanged();
-            }
-        }
+        item.Layout = DFLayout.GenerateAutoMobileLayout(GetVariables()).SaveLayout();
+        item.Type = DFLayoutType.Mobile;
 
-        private void AddDesktop_Click()
+        if (EditItems(new[] { item }))
         {
-            var item = CreateItem();
+            SaveItem(item);
+            Refresh(false, true);
+            DoChanged();
+        }
+    }
 
-            item.Layout = DFLayout.GenerateAutoDesktopLayout(GetVariables()).SaveLayout();
-            item.Type = DFLayoutType.Desktop;
+    private void AddDesktop_Click()
+    {
+        var item = CreateItem();
 
-            if (EditItems(new[] { item }))
-            {
-                SaveItem(item);
-                Refresh(false, true);
-                DoChanged();
-            }
+        item.Layout = DFLayout.GenerateAutoDesktopLayout(GetVariables()).SaveLayout();
+        item.Type = DFLayoutType.Desktop;
+
+        if (EditItems(new[] { item }))
+        {
+            SaveItem(item);
+            Refresh(false, true);
+            DoChanged();
         }
+    }
 
-        private DynamicVariableGrid? GetVariableGrid()
-            => EditorGrid.Pages?.FirstOrDefault(x => x is DynamicVariableGrid)
-                as DynamicVariableGrid;
+    private DynamicVariableGrid? GetVariableGrid()
+        => EditorGrid.Pages?.FirstOrDefault(x => x is DynamicVariableGrid)
+            as DynamicVariableGrid;
 
-        private List<DigitalFormVariable> GetVariables()
-            => GetVariableGrid()?.Items.ToList() ?? new List<DigitalFormVariable>();
+    private List<DigitalFormVariable> GetVariables()
+        => GetVariableGrid()?.Items.ToList() ?? new List<DigitalFormVariable>();
 
-        private void Design(DigitalFormLayout layout)
-        {
-            var variables = GetVariables();
+    private void Design(DigitalFormLayout layout)
+    {
+        var variables = GetVariables();
 
-            var newVariables = new List<DigitalFormVariable>();
+        var newVariables = new List<DigitalFormVariable>();
 
-            var form = new DynamicFormDesignWindow
-            {
-                Type = layout.Type
-            };
-            form.OnCreateVariable += (fieldType) =>
+        var form = new DynamicFormDesignWindow
+        {
+            Type = layout.Type
+        };
+        form.OnCreateVariable += (fieldType) =>
+        {
+            if (DynamicVariableUtils.CreateAndEdit(Item, GetVariables(), fieldType, out var variable))
             {
-                if (DynamicVariableUtils.CreateAndEdit(Item, GetVariables(), fieldType, out var variable))
-                {
-                    newVariables.Add(variable);
-                    return variable;
-                }
-                return null;
-            };
-            /*form.OnEditVariable += (variable) =>
+                newVariables.Add(variable);
+                return variable;
+            }
+            return null;
+        };
+        /*form.OnEditVariable += (variable) =>
+        {
+            var properties = variable.CreateProperties();
+            if (DynamicVariableUtils.EditProperties(Item, GetVariables(), properties.GetType(), properties))
             {
-                var properties = variable.CreateProperties();
-                if (DynamicVariableUtils.EditProperties(Item, GetVariables(), properties.GetType(), properties))
-                {
-                    variable.SaveProperties(properties);
-                    return true;
-                }
-                return false;
-            };*/
-            form.LoadLayout(layout, variables);
-            form.Initialize();
+                variable.SaveProperties(properties);
+                return true;
+            }
+            return false;
+        };*/
+        form.LoadLayout(layout, variables);
+        form.Initialize();
 
-            if (form.ShowDialog() == true)
-            {
-                layout.Layout = form.SaveLayout();
-                SaveItem(layout);
+        if (form.ShowDialog() == true)
+        {
+            layout.Layout = form.SaveLayout();
+            SaveItem(layout);
 
-                var grid = GetVariableGrid();
-                if (grid is not null)
-                {
-                    grid.SaveItems(newVariables.ToArray());
-                    grid.Refresh(false, true);
-                }
+            var grid = GetVariableGrid();
+            if (grid is not null)
+            {
+                grid.SaveItems(newVariables.ToArray());
+                grid.Refresh(false, true);
             }
         }
+    }
 
-        private bool DesignClick(CoreRow? row)
-        {
-            if (row == null)
-                return false;
+    private bool DesignClick(CoreRow? row)
+    {
+        if (row == null)
+            return false;
 
-            Design(LoadItem(row));
+        Design(LoadItem(row));
 
-            return false;
-        }
+        return false;
+    }
 
 
-        //public override void SaveItem(DigitalFormLayout item)
-        //{
-        //    bool bActive = item.Active;
-        //    foreach (var other in Items.Where(x=>(x != item) && (x.Type == item.Type)))
-        //    {
-        //        if (item.Active)
-        //        {
-        //            if (other.Active)
-        //                other.Active = false;
-        //        }
-        //        else
-        //            bActive = bActive || other.Active;
-        //    }
-        //    if (!bActive)
-        //        item.Active = true;
-        //    base.SaveItem(item);
-        //}
-
-        protected override void DoDoubleClick(object sender)
-        {
-            DesignClick(SelectedRows.FirstOrDefault());
-        }
+    //public override void SaveItem(DigitalFormLayout item)
+    //{
+    //    bool bActive = item.Active;
+    //    foreach (var other in Items.Where(x=>(x != item) && (x.Type == item.Type)))
+    //    {
+    //        if (item.Active)
+    //        {
+    //            if (other.Active)
+    //                other.Active = false;
+    //        }
+    //        else
+    //            bActive = bActive || other.Active;
+    //    }
+    //    if (!bActive)
+    //        item.Active = true;
+    //    base.SaveItem(item);
+    //}
+
+    protected override void DoDoubleClick(object sender)
+    {
+        DesignClick(SelectedRows.FirstOrDefault());
     }
 }

+ 7 - 1
inabox.wpf/DigitalForms/DynamicVariableGrid.cs

@@ -29,6 +29,12 @@ namespace InABox.DynamicGrid
             HideButton.IsEnabled = false;
 
             HiddenColumns.Add(x => x.Hidden);
+            HiddenColumns.Add(x => x.Code);
+            HiddenColumns.Add(x => x.VariableType);
+            HiddenColumns.Add(x => x.Parameters);
+            HiddenColumns.Add(x => x.Required);
+            HiddenColumns.Add(x => x.Secure);
+            HiddenColumns.Add(x => x.Retain);
         }
 
         protected override void DoReconfigure(FluentList<DynamicGridOption> options)
@@ -43,7 +49,7 @@ namespace InABox.DynamicGrid
             return Items.Where(x => x.Code == code).FirstOrDefault();
         }
 
-        private bool ShouldHide(CoreRow[] rows)
+        private static bool ShouldHide(CoreRow[] rows)
         {
             return rows.Any(x => !x.Get<DigitalFormVariable, bool>(x => x.Hidden));
         }

+ 1 - 2
inabox.wpf/DynamicGrid/DynamicDataGrid.cs

@@ -57,8 +57,7 @@ namespace InABox.DynamicGrid
             // Minimum Columns for Successful Saving
             // This should be cross-checked with the relevant Store<>
             // so that clients will (usually) provide sufficient columns for saving
-            var required = LookupFactory.RequiredColumns<TEntity>();
-            foreach (var col in required.Items)
+            foreach (var col in LookupFactory.RequiredColumns<TEntity>())
                 HiddenColumns.Add(CoreUtils.CreateLambdaExpression<TEntity>(col.Property));
 
             //HiddenColumns.Add(x => x.ID);

+ 45 - 1
inabox.wpf/DynamicGrid/DynamicOneToManyGrid.cs

@@ -28,6 +28,16 @@ namespace InABox.DynamicGrid
         private TMany[] MasterList = Array.Empty<TMany>();
         private readonly PropertyInfo property;
 
+        /// <summary>
+        /// A set of columns representing which columns have been loaded from the database.
+        /// </summary>
+        /// <remarks>
+        /// This is used to refresh the data when the columns change.<br/>
+        /// 
+        /// It is <see langword="null"/> if no data has been loaded from the database (that is, the data was gotten from
+        /// a page data handler instead.)
+        /// </remarks>
+        private HashSet<string>? LoadedColumns;
 
         protected DynamicGridCustomColumnsComponent<TMany> ColumnsComponent;
 
@@ -44,6 +54,9 @@ namespace InABox.DynamicGrid
 
         protected override void Init()
         {
+            HiddenColumns.Add(property.Name);
+            foreach (var col in LookupFactory.RequiredColumns<TMany>())
+                HiddenColumns.Add(col);
         }
 
         protected override void DoReconfigure(FluentList<DynamicGridOption> options)
@@ -133,7 +146,12 @@ namespace InABox.DynamicGrid
                     criteria.Add(new Filter<TMany>(exp).IsEqualTo(Item.ID).And(exp).IsNotEqualTo(Guid.Empty));
                     criteria.AddRange(Criteria.Items);
                     var sort = LookupFactory.DefineSort<TMany>();
-                    data = new Client<TMany>().Query(criteria.Combine(), null, sort);
+
+                    var columns = DynamicGridUtils.LoadEditorColumns(DataColumns());
+
+                    data = Client.Query(criteria.Combine(), columns, sort);
+
+                    LoadedColumns = columns.ColumnNames().ToHashSet();
                 }
             }
 
@@ -304,6 +322,32 @@ namespace InABox.DynamicGrid
             var results = new CoreTable();
             results.LoadColumns(typeof(TMany));
 
+            if (LoadedColumns is not null)
+            {
+                // Figure out which columns we still need.
+                var newColumns = columns.Where(x => !LoadedColumns.Contains(x.Property)).ToColumns();
+                if (newColumns.Any() && typeof(TMany).GetCustomAttribute<AutoEntity>() is null)
+                {
+                    var data = Client.Query(
+                        new Filter<TMany>(x => x.ID).InList(Items.Select(x => x.ID).Where(x => x != Guid.Empty).ToArray()),
+                        // We also need to add ID, so we know which item to fill.
+                        newColumns.Add(x => x.ID));
+                    foreach (var row in data.Rows)
+                    {
+                        var item = Items.FirstOrDefault(x => x.ID == row.Get<TMany, Guid>(y => y.ID));
+                        if (item is not null)
+                        {
+                            row.FillObject(item, overrideExisting: false);
+                        }
+                    }
+                    // Remember that we have now loaded this data.
+                    foreach (var column in newColumns)
+                    {
+                        LoadedColumns.Add(column.Property);
+                    }
+                }
+            }
+
             if (sort != null)
             {
                 var exp = IQueryableExtensions.ToLambda<TMany>(sort.Expression);