Просмотр исходного кода

Added 'ParentType' to DataLookupEditor, and removed EditorUtils.GetEditor() (everything should use DatabaseSchema now).

Kenric Nugteren 5 месяцев назад
Родитель
Сommit
fe16a6ccb3

+ 28 - 5
InABox.Core/DatabaseSchema/DatabaseSchema.cs

@@ -94,6 +94,24 @@ namespace InABox.Core
             _properties = new ConcurrentDictionary<Type, ImmutableSortedDictionary<string, IProperty>>();
         }
 
+        /// <summary>
+        /// Gets the editor for the specified property. If the property has a <see cref="BaseEditor"/> defined, then returns that.<br/>
+        /// Otherwise, gets a default for the property type. (<see cref="GetEditor(Type)"/>), which can be <see langword="null"/>.
+        /// </summary>
+        /// <param name="prop"></param>
+        /// <returns></returns>
+        private static BaseEditor? GetEditor(PropertyInfo prop)
+        {
+            var attribute = prop.GetCustomAttributes<BaseEditor>(true).FirstOrDefault();
+            var editor = attribute ?? EditorUtils.GetEditor(prop.PropertyType);
+            if (editor != null && !prop.CanWrite && !prop.PropertyType.HasInterface<ISubObject>())
+            {
+                editor = editor.CloneEditor();
+                editor.Editable = editor.Editable.Combine(Editable.Disabled);
+            }
+            return editor;
+        }
+
         private static void RegisterProperties(Type master, Type type, string prefix, StandardProperty? parent, Dictionary<string, IProperty> newProperties)
         {
             try
@@ -120,7 +138,7 @@ namespace InABox.Core
                     }
                     else
                     {
-                        editor = prop.GetEditor();
+                        editor = GetEditor(prop);
                     }
 
                     var captionAttr = prop.GetCustomAttribute<Caption>();
@@ -405,10 +423,15 @@ namespace InABox.Core
 
             return prop;
         }
-        public static IProperty? Property<T>(Expression<Func<T, object?>> expression) => Property(typeof(T), CoreUtils.GetFullPropertyName(expression, "."));
-        public static IProperty? Property<T, TType>(Expression<Func<T, TType>> expression) => Property(typeof(T), CoreUtils.GetFullPropertyName(expression, "."));
-
-        public static IProperty PropertyStrict(Type type, string name) => Property(type, name) ?? throw new PropertyNotFoundException(type, name);
+        public static IProperty? Property<T>(Expression<Func<T, object?>> expression) =>
+            Property(typeof(T), CoreUtils.GetFullPropertyName(expression, "."));
+        public static IProperty? Property<T, TType>(Expression<Func<T, TType>> expression) =>
+            Property(typeof(T), CoreUtils.GetFullPropertyName(expression, "."));
+
+        public static IProperty PropertyStrict(Type type, string name) =>
+            Property(type, name) ?? throw new PropertyNotFoundException(type, name);
+        public static IProperty PropertyStrict<T>(Expression<Func<T, object?>> expression) =>
+            Property(expression) ?? throw new PropertyNotFoundException(typeof(T), CoreUtils.GetFullPropertyName(expression, "."));
 
         public class PropertyNotFoundException : Exception
         {

+ 0 - 2
InABox.Core/Objects/Editors/PopupEditor.cs

@@ -4,8 +4,6 @@ namespace InABox.Core
 {
     public class PopupEditor : DataLookupEditor
     {
-        
-        
         public PopupEditor(Type type, params string[] otherfields) : base(type, otherfields)
         {
         }

+ 0 - 102
InABox.Core/Objects/Editors/Utils/EditorTypeUtils.cs

@@ -33,107 +33,5 @@ namespace InABox.Core
 
             return editor;
         }
-
-        public static BaseEditor? GetEditor(object value)
-        {
-            if (value != null)
-                return GetEditor(value.GetType());
-            return new NullEditor();
-        }
-
-        /// <summary>
-        /// Gets the editor for the specified property. If the property has a <see cref="BaseEditor"/> defined, then returns that.<br/>
-        /// Otherwise, gets a default for the property type. (<see cref="GetEditor(Type)"/>), which can be <see langword="null"/>.
-        /// </summary>
-        /// <param name="prop"></param>
-        /// <returns></returns>
-        public static BaseEditor? GetEditor(this PropertyInfo prop)
-        {
-            var attribute = prop.GetCustomAttributes<BaseEditor>(true).FirstOrDefault();
-            var editor = attribute ?? GetEditor(prop.PropertyType);
-            if (editor != null && !prop.CanWrite && !prop.PropertyType.HasInterface<ISubObject>())
-            {
-                editor = editor.CloneEditor();
-                editor.Editable = editor.Editable.Combine(Editable.Disabled);
-            }
-            return editor;
-        }
-
-        public static BaseEditor GetPropertyEditor(Type type, IProperty property, BaseEditor? defaultEditor = null)
-        {
-            BaseEditor editor = new NullEditor();
-
-            try
-            {
-                var parts = property.Name.Split('.');
-                var caption = "";
-                var page = "";
-
-                for (var i = 0; i < parts.Length; i++)
-                {
-                    var column = string.Join(".", parts.Take(i + 1));
-                    var prop = CoreUtils.GetProperty(type, column);
-                    if (column.Equals(property.Name))
-                    {
-                        editor = defaultEditor ?? property.Editor;
-                    }
-                    else
-                    {
-                        var pedit = prop.GetEditor();
-                        if (pedit is NullEditor) return pedit;
-                    }
-
-                    editor = editor == null ? new NullEditor() : (editor.Clone() as BaseEditor)!;
-
-                    var capattr = prop.GetCustomAttribute<Caption>();
-                    var subcap = capattr != null ? capattr.Text : parts[i];
-                    var path = capattr != null ? capattr.IncludePath : true;
-                    if (!string.IsNullOrWhiteSpace(subcap))
-                        caption = string.IsNullOrWhiteSpace(caption) || path == false ? subcap : string.Format("{0} {1}", caption, subcap);
-
-                    if (string.IsNullOrWhiteSpace(page))
-                    {
-                        var pageattr = prop.GetCustomAttribute<EditorSequence>();
-                        if (pageattr != null)
-                            page = pageattr.Page;
-                    }
-                }
-
-                editor.Caption = caption;
-                editor.Page = page;
-            }
-            catch (Exception)
-            {
-                if (property is CustomProperty)
-                {
-                    editor = (property.Editor.Clone() as BaseEditor)!;
-                    editor.Caption = property.Caption;
-                    editor.Page = string.IsNullOrWhiteSpace(property.Page) ? "Custom Fields" : property.Page;
-                }
-            }
-            return editor;
-        }
-
-        public static string GetCaption(this PropertyInfo prop)
-        {
-            var attribute = prop.GetCustomAttribute<Caption>();
-            var result = attribute != null ? attribute.Text : prop.Name;
-            return result;
-        }
-
-        public static int GetSequence(this PropertyInfo prop)
-        {
-            var attribute = prop.GetCustomAttribute<EditorSequence>();
-            var result = attribute != null ? attribute.Sequence : 999;
-            return result;
-        }
-
-        public static bool IsCalculated(this PropertyInfo prop)
-        {
-            return prop.GetCustomAttribute<AggregateAttribute>() != null
-                || prop.GetCustomAttribute<FormulaAttribute>() != null
-                || prop.GetCustomAttribute<ConditionAttribute>() != null
-                || prop.GetCustomAttribute<ComplexFormulaAttribute>() != null;
-        }
     }
 }

+ 55 - 3
inabox.wpf/Dashboard/DynamicDashboardDataComponent.cs

@@ -9,18 +9,30 @@ using System.Threading.Tasks;
 
 namespace InABox.Wpf.Dashboard;
 
-public interface IDynamicDashboardDataQuery
+public interface IDynamicDashboardTable
 {
-    Type Type { get; }
-
     string Key { get; set; }
 
+    IEnumerable<CoreColumn> CoreColumns { get; }
+}
+
+public interface IDynamicDashboardDataQuery : IDynamicDashboardTable
+{
+    Type Type { get; }
+
     IFilter? Filter { get; set; }
 
     IColumns Columns { get; set; }
 
     ISortOrder? SortOrder { get; set; }
+
+    IEnumerable<CoreColumn> IDynamicDashboardTable.CoreColumns => Columns.Columns().Select(x => new CoreColumn
+    {
+        ColumnName = x.Name,
+        DataType = x.Type
+    });
 }
+
 public class DynamicDashboardDataQuery<T> : IDynamicDashboardDataQuery
     where T : Entity, IRemotable, new()
 {
@@ -57,10 +69,50 @@ public class DynamicDashboardDataQuery<T> : IDynamicDashboardDataQuery
     #endregion
 }
 
+public class DynamicDashboardAdditionalTable : IDynamicDashboardTable
+{
+    public string Key { get; set; } = "";
+
+    public List<CoreColumn> Columns { get; set; } = new();
+
+    public string? Script { get; set; }
+
+    IEnumerable<CoreColumn> IDynamicDashboardTable.CoreColumns => Columns;
+
+    public static string DefaultScript()
+    {
+        return @"using InABox.Wpf.Dashboard;
+
+public class Module
+{
+    public void PopulateTable(CoreTable table, DynamicDashboardData data)
+    {
+        // Populate 'table' using the data from 'data'.
+    }
+}";
+    }
+}
+
 public class DynamicDashboardDataComponent
 {
     public List<IDynamicDashboardDataQuery> Queries { get; set; } = new();
 
+    public List<DynamicDashboardAdditionalTable> AdditionalTables { get; set; } = new();
+
+    public IEnumerable<IDynamicDashboardTable> Tables => Queries.Concat<IDynamicDashboardTable>(AdditionalTables);
+
+    public IDynamicDashboardTable GetTable(string key)
+    {
+        return Tables.FirstOrDefault(x => x.Key == key)
+            ?? throw new KeyNotFoundException($"Data query '{key}' does not exist.");
+    }
+
+    public bool TryGetTable(string key, [NotNullWhen(true)] out IDynamicDashboardTable? query)
+    {
+        query = Tables.FirstOrDefault(x => x.Key == key);
+        return query != null;
+    }
+
     public IDynamicDashboardDataQuery GetQuery(string key)
     {
         return Queries.FirstOrDefault(x => x.Key == key)

+ 16 - 0
inabox.wpf/DynamicGrid/DynamicGridColumn/DynamicGridColumn.cs

@@ -97,4 +97,20 @@ public class DynamicGridColumn : DynamicColumnBase
             Editor = column.Editor.CloneEditor()
         };
     }
+
+    public static DynamicGridColumn? FromCoreColumn(CoreColumn column)
+    {
+        var editor = EditorUtils.GetEditor(column.DataType);
+        if (editor is null) return null;
+
+        return new DynamicGridColumn
+        {
+            ColumnName = column.ColumnName,
+            Width = editor.Width,
+            Caption = editor.Caption,
+            Format = editor.Format,
+            Alignment = editor.Alignment,
+            Editor = editor.CloneEditor()
+        };
+    }
 }

+ 14 - 0
inabox.wpf/DynamicGrid/DynamicGridColumn/DynamicGridColumns.cs

@@ -52,6 +52,20 @@ public class DynamicGridColumns : List<DynamicGridColumn>, IGlobalConfigurationS
 
         return this;
     }
+    public static DynamicGridColumns ExtractColumns(Type type, IColumns columns)
+    {
+        var cols = new DynamicGridColumns();
+        var master = new DynamicGridColumns().ExtractColumns(type);
+
+        foreach (var col in columns)
+        {
+            var mc = master.FirstOrDefault(x => x.ColumnName.Equals(col.Property));
+            if (mc != null && mc.Editor is not NullEditor && mc.Editor.Visible != Visible.Hidden)
+                cols.Add(mc);
+        }
+
+        return cols;
+    }
 
     public static DynamicGridColumn CreateColumn<TType>(
         Expression<Func<TType, object?>> member,

+ 11 - 43
inabox.wpf/DynamicGrid/DynamicGridCustomColumnsComponent.cs

@@ -40,31 +40,17 @@ public class DynamicGridCustomColumnsComponent<T>
         if (!columns.Any())
             columns = Grid.GenerateColumns();
 
-        var removes = columns.Where(x => x is null || string.IsNullOrWhiteSpace(x.ColumnName) || DatabaseSchema.Property(typeof(T), x.ColumnName) == null || GetColumnEditor(x) is NullEditor)
-           .ToArray();
-        foreach (var remove in removes)
-            columns.Remove(remove);
-
-        foreach (var column in columns)
-            try
-            {
-                var prop = DatabaseSchema.Property(typeof(T), column.ColumnName);
-                if (prop != null)
-                {
-                    column.Editor = prop.Editor;
-                }
-                else
-                {
-                    var type = CoreUtils.GetProperty(typeof(T), column.ColumnName);
-                    column.Editor = type.GetEditor() ?? new NullEditor();
-                }
-            }
-            catch (Exception e)
-            {
-                Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-            }
-
-        columns.RemoveAll(x => DatabaseSchema.Property(typeof(T), x.ColumnName) == null || GetColumnEditor(x) is NullEditor);
+        columns.RemoveAll(x =>
+        {
+            if (x.ColumnName.IsNullOrWhiteSpace()) return true;
+
+            var prop = DatabaseSchema.Property(typeof(T), x.ColumnName);
+            if (prop is null || prop.Editor is NullEditor) return true;
+
+            x.Editor = prop.Editor;
+            return false;
+        });
+
         return columns;
     }
 
@@ -82,24 +68,6 @@ public class DynamicGridCustomColumnsComponent<T>
         return tag;
     }
 
-    private static BaseEditor GetColumnEditor(DynamicGridColumn column)
-    {
-        try
-        {
-            var prop = DatabaseSchema.Property(typeof(T), column.ColumnName);
-            if (prop != null) return prop.Editor;
-
-            var type = CoreUtils.GetProperty(typeof(T), column.ColumnName);
-            return type.GetEditor() ?? new NullEditor();
-        }
-        catch (Exception e)
-        {
-            Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
-        }
-
-        return new NullEditor();
-    }
-
     public void LoadColumnsMenu(ContextMenu menu)
     {
         menu.AddSeparatorIfNeeded();