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

Fix to constants not being preserved in Filter Editor when changing operator; caused FilterEditor to not allow using certain operators with certain types

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

+ 50 - 0
InABox.Core/Query/Filter.cs

@@ -90,6 +90,56 @@ namespace InABox.Core
         Not = byte.MaxValue
     }
 
+    public static class Operators
+    {
+        private static Operator[] _base = new Operator[]
+        {
+            Operator.IsEqualTo,
+            Operator.IsNotEqualTo,
+        };
+        private static Operator[] _comparisonOps = new Operator[]
+        {
+            Operator.IsGreaterThan,
+            Operator.IsGreaterThanOrEqualTo,
+            Operator.IsLessThan,
+            Operator.IsLessThanOrEqualTo,
+        };
+        private static Operator[] _stringOps = new Operator[]
+        {
+            Operator.Contains,
+            Operator.BeginsWith,
+            Operator.EndsWith,
+            Operator.Regex,
+            Operator.Resembles,
+        };
+        private static Operator[] _inOps = new Operator[]
+        {
+            Operator.InList,
+            Operator.NotInList,
+            Operator.InQuery,
+            Operator.NotInQuery,
+        };
+        private static Operator[] _end = new Operator[]
+        {
+            Operator.All,
+            Operator.None,
+            Operator.Not,
+        };
+
+        public static Operator[] GetOperators(Type type)
+        {
+            var arrs = new Operator[][]
+            {
+                _base,
+                type == typeof(string) || type == typeof(DateTime) || type == typeof(TimeSpan) || type.IsNumeric() ? _comparisonOps : Array.Empty<Operator>(),
+                type == typeof(string) ? _stringOps : Array.Empty<Operator>(),
+                _inOps,
+                _end
+            };
+            return CoreUtils.Concatenate(arrs);
+        }
+    }
+
     public enum ListOperator
     {
         Includes,

+ 23 - 5
inabox.wpf/DynamicGrid/Editors/FilterEditor/FilterNode.cs

@@ -73,7 +73,7 @@ public class FilterNode<T> : BaseFilterNode
         this.filterType = filterType;
 
         Property = new(filter.Property) { Margin = new Thickness(0, 0, 5, 0) };
-        Operator = new(filter.Operator, filter.IsNot) { Margin = new Thickness(0, 0, 5, 0) };
+        Operator = CreateOperatorNode(Property.SelectedProperty, filter.Operator, filter.IsNot);
 
         ValuePlaceHolder = CreateValuePlaceHolder();
         
@@ -81,7 +81,6 @@ public class FilterNode<T> : BaseFilterNode
         SetValueNode(valueNode ?? new EmptyValueNode(), filter.Value);
 
         Constant = CreateConstantNode(Property.SelectedProperty, filter.Operator, filter.Value as FilterConstant?);
-        CheckValueVisibilities();
 
         CustomValue = CreateCustomValueNode(Property.SelectedProperty, filter.Operator, filter.Value as CustomFilterValue);
         CheckValueVisibilities();
@@ -95,7 +94,6 @@ public class FilterNode<T> : BaseFilterNode
         OrButton.Click += OrButton_Click;
 
         Property.PropertyChanged += Property_PropertyChanged;
-        Operator.OperatorChanged += Operator_OperatorChanged;
         
         Add(ClearButton, 0, 0);
         if(LabelButton != null)
@@ -259,6 +257,23 @@ public class FilterNode<T> : BaseFilterNode
         Add(Value, 0, 6);
         CheckValueVisibilities();
     }
+
+    private OperatorNode CreateOperatorNode(string? propertyName, Operator op, bool isNot)
+    {
+        Operator[] operators;
+        if (!string.IsNullOrWhiteSpace(propertyName) && DatabaseSchema.Property(typeof(T), propertyName) is IProperty property)
+        {
+            operators = Operators.GetOperators(property.PropertyType);
+        }
+        else
+        {
+            operators = [];
+        }
+        var opNode = new OperatorNode(op, isNot, operators) { Margin = new Thickness(0, 0, 5, 0) };
+        opNode.Visibility = operators.Length > 0 ? Visibility.Visible : Visibility.Collapsed;
+        opNode.OperatorChanged += Operator_OperatorChanged;
+        return opNode;
+    }
         
     private ConstantNode? CreateConstantNode(string? propertyName, Operator op, FilterConstant? constantvalue)
     {
@@ -315,6 +330,10 @@ public class FilterNode<T> : BaseFilterNode
 
     private void Property_PropertyChanged(string? property)
     {
+        Children.Remove(Operator);
+        Operator = CreateOperatorNode(Property.SelectedProperty, Operator.SelectedOperator, Operator.IsNot);
+        Add(Operator, 0, 3);
+
         if (Constant is not null)
         {
             Children.Remove(Constant);
@@ -350,12 +369,11 @@ public class FilterNode<T> : BaseFilterNode
 
     private void Operator_OperatorChanged(Operator op, bool isNot)
     {
-
         if (Constant is not null)
         {
             Children.Remove(Constant);
         }
-        Constant = CreateConstantNode(Property.SelectedProperty, Operator.SelectedOperator, null);
+        Constant = CreateConstantNode(Property.SelectedProperty, Operator.SelectedOperator, Constant?.SelectedConstant);
         if (Constant is not null)
         {
             Add(Constant, 0, 4);

+ 6 - 3
inabox.wpf/DynamicGrid/Editors/FilterEditor/Nodes/OperatorNode.cs

@@ -15,14 +15,17 @@ public class OperatorNode : StackPanel
 
     public event OperatorChangedHandler? OperatorChanged;
 
-    public Operator SelectedOperator => (Operator)_boxes.Last().SelectedItem;
+    public Operator SelectedOperator => (Operator?)_boxes.Last().SelectedItem ?? Operator.IsEqualTo;
 
     public bool IsNot => _boxes.Count % 2 == 0;
 
     private List<ComboBox> _boxes = new List<ComboBox>();
 
-    public OperatorNode(Operator op, bool isNot)
+    private Operator[] _operators;
+
+    public OperatorNode(Operator op, bool isNot, Operator[] operators)
     {
+        _operators = operators;
         Orientation = Orientation.Horizontal;
         VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
 
@@ -44,7 +47,7 @@ public class OperatorNode : StackPanel
         box.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
         box.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;
 
-        foreach (var value in Enum.GetValues<Operator>())
+        foreach (var value in _operators)
         {
             box.Items.Add(value);
         }

+ 1 - 0
inabox.wpf/DynamicGrid/Editors/FilterEditor/Nodes/PropertyNode.cs

@@ -69,5 +69,6 @@ public class PropertyNode<T> : Button
     public void Clear()
     {
         SelectedProperty = null;
+        PropertyChanged?.Invoke(null);
     }
 }