Browse Source

Added filter button to task panel

Kenric Nugteren 1 year ago
parent
commit
c3792dae94

+ 4 - 4
prs.desktop/Panels/Equipment/EquipmentPanel.xaml.cs

@@ -196,14 +196,14 @@ namespace PRSDesktop
         
         private bool _Equipment_OnFilterRecord(CoreRow row)
         {
-            if (!String.IsNullOrWhiteSpace(_searchfilter))
+            if (!string.IsNullOrWhiteSpace(_searchfilter))
             {
                 for (int i=0; i<row.Table.Columns.Count; i++)
                 {
                     if ((row.Table.Columns[i].DataType == typeof(String)))
                     {
-                        string value = row.Values[i] as string;
-                        if (!String.IsNullOrEmpty(value) && value.ToUpper().Contains(_searchfilter.ToUpper()))
+                        var value = row.Values[i] as string;
+                        if (!string.IsNullOrEmpty(value) && value.ToUpper().Contains(_searchfilter.ToUpper()))
                             return true;
                     }
                 }
@@ -234,7 +234,7 @@ namespace PRSDesktop
         
         private void Search_OnTextChanged(object sender, TextChangedEventArgs e)
         {
-            if (String.IsNullOrEmpty(Search.Text)  && !String.Equals(Search.Text, _searchfilter))
+            if (string.IsNullOrEmpty(Search.Text)  && !string.Equals(Search.Text, _searchfilter))
             {
                 _searchfilter = "";
                 _Equipment.Refresh(false, false);

+ 208 - 208
prs.desktop/Panels/Tasks/TaskGrid.cs

@@ -6,281 +6,281 @@ using System.Windows;
 using System.Windows.Controls;
 using Comal.Classes;
 using InABox.Clients;
+using InABox.Configuration;
 using InABox.Core;
 using InABox.DynamicGrid;
 using InABox.WPF;
 
-namespace PRSDesktop
+namespace PRSDesktop;
+
+public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
 {
-    public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
+    public TaskGrid()
     {
-        public TaskGrid()
-        {
-            ActionColumns.Add(new DynamicImageColumn(PRSDesktop.Resources.menu.AsBitmapImage(), FormMenuClick));
+        ActionColumns.Add(new DynamicImageColumn(PRSDesktop.Resources.menu.AsBitmapImage(), FormMenuClick));
 
-            HiddenColumns.Add(x => x.EmployeeLink.ID);
-            HiddenColumns.Add(x => x.EmployeeLink.Deleted);
-            HiddenColumns.Add(x => x.ManagerLink.Deleted);       
+        HiddenColumns.Add(x => x.EmployeeLink.ID);
+        HiddenColumns.Add(x => x.EmployeeLink.Deleted);
+        HiddenColumns.Add(x => x.ManagerLink.Deleted);       
 
-            OnCustomiseEditor += CustomiseEditor;
-            OnBeforeSave += BeforeSave;
-        }
+        OnCustomiseEditor += CustomiseEditor;
+        OnBeforeSave += BeforeSave;
+    }
 
-        protected override void DoReconfigure(FluentList<DynamicGridOption> options)
-        {
-            base.DoReconfigure(options);
+    protected override void DoReconfigure(FluentList<DynamicGridOption> options)
+    {
+        base.DoReconfigure(options);
 
-            options.AddRange(DynamicGridOption.SelectColumns, DynamicGridOption.FilterRows);
-        }
+        options.AddRange(DynamicGridOption.SelectColumns, DynamicGridOption.FilterRows);
+    }
 
-        public Guid MyID { get; set; } = CoreUtils.FullGuid;
+    public Guid MyID { get; set; } = CoreUtils.FullGuid;
 
-        private bool FormMenuClick(CoreRow? row)
-        {
-            if (row is null)
-                return false;
+    private bool FormMenuClick(CoreRow? row)
+    {
+        if (row is null)
+            return false;
 
-            var kanbanID = row.Get<Kanban, Guid>(x => x.ID);
+        var kanbanID = row.Get<Kanban, Guid>(x => x.ID);
 
-            var menu = new ContextMenu();
+        var menu = new ContextMenu();
 
-            DynamicGridUtils.PopulateFormMenu<KanbanForm, Kanban, KanbanLink>(menu, kanbanID, () => row.ToObject<Kanban>());
+        DynamicGridUtils.PopulateFormMenu<KanbanForm, Kanban, KanbanLink>(menu, kanbanID, () => row.ToObject<Kanban>());
 
-            menu.IsOpen = true;
+        menu.IsOpen = true;
 
-            return false;
-        }
+        return false;
+    }
 
-        private void CustomiseEditor(IDynamicEditorForm sender, Kanban[]? items, DynamicGridColumn column, BaseEditor editor)
-        {
-            var kanban = items?.FirstOrDefault();
-            if (kanban is null) return;
+    private void CustomiseEditor(IDynamicEditorForm sender, Kanban[]? items, DynamicGridColumn column, BaseEditor editor)
+    {
+        var kanban = items?.FirstOrDefault();
+        if (kanban is null) return;
 
-            var bFullControl = IsFullControl(new[] { kanban });
-            bool? enabled = null;
-            switch (column.ColumnName)
-            {
-                case "Private":
-                    enabled = kanban.EmployeeLink.ID == MyID && kanban.ManagerLink.ID == MyID;
-                    break;
-                case "Description":
-                    enabled = kanban.ID == Guid.Empty || (bFullControl && !kanban.Private);
-                    break;
-                case "EmployeeLink.ID":
-                    enabled = bFullControl && !kanban.Private;
-                    break;
-                case "ManagerLink.ID":
-                    enabled = bFullControl && !kanban.Private;
-                    break;
-                case "Category":
-                    enabled = bFullControl && !kanban.Private;
-                    break;
-                case "Closed":
-                    enabled = bFullControl || Security.IsAllowed<CanCloseOthersTasks>();
-                    break;
-            }
-            if(enabled != null)
-            {
-                editor.Editable = enabled.Value ? Editable.Enabled : Editable.Disabled;
-            }
+        var bFullControl = IsFullControl(new[] { kanban });
+        bool? enabled = null;
+        switch (column.ColumnName)
+        {
+            case "Private":
+                enabled = kanban.EmployeeLink.ID == MyID && kanban.ManagerLink.ID == MyID;
+                break;
+            case "Description":
+                enabled = kanban.ID == Guid.Empty || (bFullControl && !kanban.Private);
+                break;
+            case "EmployeeLink.ID":
+                enabled = bFullControl && !kanban.Private;
+                break;
+            case "ManagerLink.ID":
+                enabled = bFullControl && !kanban.Private;
+                break;
+            case "Category":
+                enabled = bFullControl && !kanban.Private;
+                break;
+            case "Closed":
+                enabled = bFullControl || Security.IsAllowed<CanCloseOthersTasks>();
+                break;
         }
+        if(enabled != null)
+        {
+            editor.Editable = enabled.Value ? Editable.Enabled : Editable.Disabled;
+        }
+    }
 
-        private bool IsFullControl(Kanban[] kanbans)
+    private bool IsFullControl(Kanban[] kanbans)
+    {
+        foreach (var kanban in kanbans)
         {
-            foreach (var kanban in kanbans)
+            if (!MyID.Equals(kanban.ManagerLink.ID) && !MyID.Equals(kanban.EmployeeLink.ID))
             {
-                if (!MyID.Equals(kanban.ManagerLink.ID) && !MyID.Equals(kanban.EmployeeLink.ID))
-                {
-                    // If you can change others tasks, IsFullControl is true - but we don't check at the beginning of the function
-                    // to save checking security tokens every time.
-                    return Security.IsAllowed<CanChangeOthersTasks>();
-                }
+                // If you can change others tasks, IsFullControl is true - but we don't check at the beginning of the function
+                // to save checking security tokens every time.
+                return Security.IsAllowed<CanChangeOthersTasks>();
             }
-            return true;
         }
+        return true;
+    }
+
+    private void BeforeSave(IDynamicEditorForm editor, BaseObject[] items)
+    {
+        EnsureAssignee(editor, items.FirstOrDefault() as Kanban);
+        EnsureAllocator(editor, items.FirstOrDefault() as Kanban);
+    }
 
-        private void BeforeSave(IDynamicEditorForm editor, BaseObject[] items)
+    protected override void SelectPage(object sender, BaseObject[]? items)
+    {
+        base.SelectPage(sender, items);
+        var tab = sender as TabItem;
+        if(tab?.Content is KanbanSubscriberGrid grid)
         {
-            EnsureAssignee(editor, items.FirstOrDefault() as Kanban);
-            EnsureAllocator(editor, items.FirstOrDefault() as Kanban);
+            grid.EnsureAssignee();
+            grid.EnsureAllocator();
         }
+    }
 
-        protected override void SelectPage(object sender, BaseObject[]? items)
+    protected override void AfterLoad(IDynamicEditorForm editor, Kanban[] kanbans)
+    {
+        base.AfterLoad(editor, kanbans);
+        //EnsureAssignee(editor, kanbans.FirstOrDefault());
+        //EnsureAllocator(editor, kanbans.FirstOrDefault());
+
+        if (MyID == CoreUtils.FullGuid)
         {
-            base.SelectPage(sender, items);
-            var tab = sender as TabItem;
-            if(tab?.Content is KanbanSubscriberGrid grid)
-            {
-                grid.EnsureAssignee();
-                grid.EnsureAllocator();
-            }
+            var row = new Client<Employee>()
+                .Query(new Filter<Employee>(x => x.UserLink.ID).IsEqualTo(ClientFactory.UserGuid), new Columns<Employee>(x => x.ID)).Rows
+                .FirstOrDefault();
+            if (row != null)
+                MyID = row.Get<Employee, Guid>(x => x.ID);
         }
 
-        protected override void AfterLoad(IDynamicEditorForm editor, Kanban[] kanbans)
-        {
-            base.AfterLoad(editor, kanbans);
-            //EnsureAssignee(editor, kanbans.FirstOrDefault());
-            //EnsureAllocator(editor, kanbans.FirstOrDefault());
+        //if (kanbans.FirstOrDefault().ID == Guid.Empty)
+        //    ReloadForms<Kanban, KanbanForm, KanbanTypeForm>(editor, kanbans.FirstOrDefault(), x => x.Type.ID, kanbans.FirstOrDefault().Type.ID);
+    }
 
-            if (MyID == CoreUtils.FullGuid)
-            {
-                var row = new Client<Employee>()
-                    .Query(new Filter<Employee>(x => x.UserLink.ID).IsEqualTo(ClientFactory.UserGuid), new Columns<Employee>(x => x.ID)).Rows
-                    .FirstOrDefault();
-                if (row != null)
-                    MyID = row.Get<Employee, Guid>(x => x.ID);
-            }
+    protected override Dictionary<string, object?> EditorValueChanged(IDynamicEditorForm editor, Kanban[] items, string name, object value)
+    {
+        var result = base.EditorValueChanged(editor, items, name, value);
 
-            //if (kanbans.FirstOrDefault().ID == Guid.Empty)
-            //    ReloadForms<Kanban, KanbanForm, KanbanTypeForm>(editor, kanbans.FirstOrDefault(), x => x.Type.ID, kanbans.FirstOrDefault().Type.ID);
+        if (name == "Type.ID")
+        {
+            //ReloadForms<Kanban, KanbanForm, KanbanTypeForm>(editor, items.FirstOrDefault(), x => x.Type.ID,
+            //    value != null ? (Guid)value : Guid.Empty);
         }
-
-        protected override Dictionary<string, object?> EditorValueChanged(IDynamicEditorForm editor, Kanban[] items, string name, object value)
+        else if (name == "EmployeeLink.ID")
         {
-            var result = base.EditorValueChanged(editor, items, name, value);
-
-            if (name == "Type.ID")
-            {
-                //ReloadForms<Kanban, KanbanForm, KanbanTypeForm>(editor, items.FirstOrDefault(), x => x.Type.ID,
-                //    value != null ? (Guid)value : Guid.Empty);
-            }
-            else if (name == "EmployeeLink.ID")
-            {
-                EnsureAssignee(editor, items.FirstOrDefault());
-                var enabled = items.FirstOrDefault()?.ManagerLink.UserLink.ID == ClientFactory.UserGuid &&
-                              (Guid)(value ?? Guid.Empty) == items.FirstOrDefault()?.ManagerLink.ID;
-                editor.FindEditor("Private").IsEnabled = enabled;
-            }
-            else if (name == "ManagerLink.ID")
-            {
-                EnsureAllocator(editor, items.FirstOrDefault());
-                var enabled = items.FirstOrDefault()?.EmployeeLink.UserLink.ID == ClientFactory.UserGuid &&
-                              (Guid)(value ?? Guid.Empty) == items.FirstOrDefault()?.EmployeeLink.ID;
-                editor.FindEditor("Private").IsEnabled = enabled;
-            }
-            else if (name == "Private")
+            EnsureAssignee(editor, items.FirstOrDefault());
+            var enabled = items.FirstOrDefault()?.ManagerLink.UserLink.ID == ClientFactory.UserGuid &&
+                          (Guid)(value ?? Guid.Empty) == items.FirstOrDefault()?.ManagerLink.ID;
+            editor.FindEditor("Private").IsEnabled = enabled;
+        }
+        else if (name == "ManagerLink.ID")
+        {
+            EnsureAllocator(editor, items.FirstOrDefault());
+            var enabled = items.FirstOrDefault()?.EmployeeLink.UserLink.ID == ClientFactory.UserGuid &&
+                          (Guid)(value ?? Guid.Empty) == items.FirstOrDefault()?.EmployeeLink.ID;
+            editor.FindEditor("Private").IsEnabled = enabled;
+        }
+        else if (name == "Private")
+        {
+            var enabled = !Equals(value, true);
+            var employeeEditor = editor.FindEditor("EmployeeLink.ID");
+            var managerEditor = editor.FindEditor("ManagerLink.ID");
+            employeeEditor.IsEnabled = enabled;
+            managerEditor.IsEnabled = enabled;
+            if (!enabled)
             {
-                var enabled = !Equals(value, true);
-                var employeeEditor = editor.FindEditor("EmployeeLink.ID");
-                var managerEditor = editor.FindEditor("ManagerLink.ID");
-                employeeEditor.IsEnabled = enabled;
-                managerEditor.IsEnabled = enabled;
-                if (!enabled)
+                employeeEditor.SetValue(employeeEditor.ColumnName, MyID);
+                managerEditor.SetValue(managerEditor.ColumnName, MyID);
+
+                foreach(var item in items)
                 {
-                    employeeEditor.SetValue(employeeEditor.ColumnName, MyID);
-                    managerEditor.SetValue(managerEditor.ColumnName, MyID);
-
-                    foreach(var item in items)
-                    {
-                        item.EmployeeLink.ID = MyID;
-                        item.ManagerLink.ID = MyID;
-                    }
+                    item.EmployeeLink.ID = MyID;
+                    item.ManagerLink.ID = MyID;
                 }
             }
-
-            return result;
         }
 
-        private static KanbanSubscriberGrid? EnsurePage(IDynamicEditorForm editor, Kanban item)
-        {
-            var type = typeof(IDynamicOneToManyGrid<,>).MakeGenericType(typeof(Kanban), typeof(KanbanSubscriber));
-            var page = editor.Pages.FirstOrDefault(x => x.GetType().GetInterfaces().Contains(type)) as KanbanSubscriberGrid;
+        return result;
+    }
 
-            if (page != null && !page.Ready)
-                page.Load(item, null);
+    private static KanbanSubscriberGrid? EnsurePage(IDynamicEditorForm editor, Kanban item)
+    {
+        var type = typeof(IDynamicOneToManyGrid<,>).MakeGenericType(typeof(Kanban), typeof(KanbanSubscriber));
+        var page = editor.Pages.FirstOrDefault(x => x.GetType().GetInterfaces().Contains(type)) as KanbanSubscriberGrid;
 
-            return page;
-        }
+        if (page != null && !page.Ready)
+            page.Load(item, null);
 
-        private static void EnsureAssignee(IDynamicEditorForm editor, Kanban? kanban)
-        {
-            if (kanban is null) return;
+        return page;
+    }
 
-            var page = EnsurePage(editor, kanban);
-            if (page is null) return;
+    private static void EnsureAssignee(IDynamicEditorForm editor, Kanban? kanban)
+    {
+        if (kanban is null) return;
 
-            page.EnsureAssignee();
-        }
+        var page = EnsurePage(editor, kanban);
+        if (page is null) return;
 
-        private static void EnsureAllocator(IDynamicEditorForm editor, Kanban? kanban)
-        {
-            if (kanban is null) return;
+        page.EnsureAssignee();
+    }
 
-            var page = EnsurePage(editor, kanban);
-            if (page is null) return;
+    private static void EnsureAllocator(IDynamicEditorForm editor, Kanban? kanban)
+    {
+        if (kanban is null) return;
 
-            page.EnsureAllocator();
-        }
+        var page = EnsurePage(editor, kanban);
+        if (page is null) return;
+
+        page.EnsureAllocator();
+    }
 
-        protected override void Reload(Filters<Kanban> criteria, Columns<Kanban> columns, ref SortOrder<Kanban>? sort,
-            Action<CoreTable?, Exception?> action)
+    protected override void Reload(Filters<Kanban> criteria, Columns<Kanban> columns, ref SortOrder<Kanban>? sort,
+        Action<CoreTable?, Exception?> action)
+    {
+        if (Host.Job != null)
         {
-            if (Host.Job != null)
-            {
-                if (Host.Job.ID != Guid.Empty)
-                    criteria.Add(new Filter<Kanban>(x => x.JobLink.ID).IsEqualTo(Host.Job.ID));
-                else
-                    criteria.Add(new Filter<Kanban>(x => x.JobLink.ID).None());
-            }
+            if (Host.Job.ID != Guid.Empty)
+                criteria.Add(new Filter<Kanban>(x => x.JobLink.ID).IsEqualTo(Host.Job.ID));
+            else
+                criteria.Add(new Filter<Kanban>(x => x.JobLink.ID).None());
+        }
 
-            criteria.Add(new Filter<Kanban>(x => x.Created).IsGreaterThanOrEqualTo(DateTime.Now.AddDays(-365)));
+        criteria.Add(new Filter<Kanban>(x => x.Created).IsGreaterThanOrEqualTo(DateTime.Now.AddDays(-365)));
 
-            base.Reload(criteria, columns, ref sort, action);
-        }
+        base.Reload(criteria, columns, ref sort, action);
+    }
 
-        #region ITaskControl Support
+    #region ITaskControl Support
 
-        public KanbanViewType KanbanViewType => KanbanViewType.List;
+    public KanbanViewType KanbanViewType => KanbanViewType.List;
 
-        public ITaskHost Host { get; set; }
+    public ITaskHost Host { get; set; }
 
-        public bool IsReady { get; set; }
+    public bool IsReady { get; set; }
 
-        public string SectionName => "Task List";
+    public string SectionName => "Task List";
 
-        public DataModel DataModel(Selection selection)
-        {
-            return new AutoDataModel<Kanban>(new Filter<Kanban>(x => x.ID).IsEqualTo(Guid.Empty));
-        }
+    public DataModel DataModel(Selection selection)
+    {
+        return new AutoDataModel<Kanban>(new Filter<Kanban>(x => x.ID).IsEqualTo(Guid.Empty));
+    }
 
-        public void Refresh()
-        {
-            Refresh(false, true);
-        }
+    public void Refresh()
+    {
+        Refresh(false, true);
+    }
 
-        public void Refresh(bool resetselection)
-        {
-            Refresh(false, true);
-            // reset selected rows here
-        }
+    public void Refresh(bool resetselection)
+    {
+        Refresh(false, true);
+        // reset selected rows here
+    }
 
-        public void Setup()
-        {
-            Refresh(true, false);
-        }
+    public void Setup()
+    {
+        Refresh(true, false);
+    }
 
-        public IEnumerable<TaskModel> SelectedModels(TaskModel? sender = null)
-        {
-            MessageBox.Show("TaskListControl.SelectedModels() is not Implemented!");
-            return Array.Empty<TaskModel>();
-        }
+    public IEnumerable<TaskModel> SelectedModels(TaskModel? sender = null)
+    {
+        MessageBox.Show("TaskListControl.SelectedModels() is not Implemented!");
+        return Array.Empty<TaskModel>();
+    }
 
-        protected override bool CanCreateItems()
-        {
-            return Host.Job == null || Host.Job.ID != Guid.Empty;
-        }
+    protected override bool CanCreateItems()
+    {
+        return Host.Job == null || Host.Job.ID != Guid.Empty;
+    }
 
-        protected override Kanban CreateItem()
+    protected override Kanban CreateItem()
+    {
+        var result = base.CreateItem();
+        if (Host.Job != null)
         {
-            var result = base.CreateItem();
-            if (Host.Job != null)
-            {
-                result.JobLink.ID = Host.Job.ID;
-                result.JobLink.Synchronise(Host.Job);
-            }
-            return result;
+            result.JobLink.ID = Host.Job.ID;
+            result.JobLink.Synchronise(Host.Job);
         }
-
-        #endregion
+        return result;
     }
+
+    #endregion
 }

+ 62 - 0
prs.desktop/Panels/Tasks/TaskPanel.xaml.cs

@@ -15,6 +15,7 @@ using Syncfusion.Pdf.Graphics;
 using Syncfusion.Pdf;
 using System.Drawing;
 using System.ComponentModel;
+using InABox.Wpf;
 
 namespace PRSDesktop
 {
@@ -24,6 +25,67 @@ namespace PRSDesktop
         public bool RequireTaskTypes { get; set; } = false;
     }
 
+    public class TaskPanelFilterButton : FilterButton<Kanban>
+    {
+        public TaskPanelFilterButton() : base(
+            new GlobalConfiguration<CoreFilterDefinitions>(nameof(Kanban)),
+            new UserConfiguration<CoreFilterDefinitions>(nameof(Kanban)))
+        {
+        }
+
+        public static Filter<Kanban> ConvertFilterToKanbanFilter(Filter<Kanban>? kanbanFilter)
+        {
+            if (kanbanFilter is null)
+            {
+                return new Filter<Kanban>().All();
+            }
+            else if (CoreUtils.TryFindMemberExpression(kanbanFilter.Expression, out var mexp))
+            {
+                var prop = CoreUtils.GetFullPropertyName(mexp, ".");
+                var filter = new Filter<Kanban>(prop)
+                {
+                    Operator = kanbanFilter.Operator,
+                    Value = kanbanFilter.Value
+                };
+
+                filter.Ands.AddRange(kanbanFilter.Ands.Select(ConvertFilterToKanbanFilter));
+                filter.Ors.AddRange(kanbanFilter.Ors.Select(ConvertFilterToKanbanFilter));
+
+                return filter;
+            }
+            else
+            {
+                return new Filter<Kanban>().None();
+            }
+        }
+
+        public static Filter<KanbanSubscriber> ConvertFilterToSubscriberFilter(Filter<IKanban>? kanbanFilter)
+        {
+            if (kanbanFilter is null)
+            {
+                return new Filter<KanbanSubscriber>().All();
+            }
+            else if (CoreUtils.TryFindMemberExpression(kanbanFilter.Expression, out var mexp))
+            {
+                var prop = CoreUtils.GetFullPropertyName(mexp, ".");
+                var filter = new Filter<KanbanSubscriber>(nameof(KanbanSubscriber.Kanban) + "." + prop)
+                {
+                    Operator = kanbanFilter.Operator,
+                    Value = kanbanFilter.Value
+                };
+
+                filter.Ands.AddRange(kanbanFilter.Ands.Select(ConvertFilterToSubscriberFilter));
+                filter.Ors.AddRange(kanbanFilter.Ors.Select(ConvertFilterToSubscriberFilter));
+
+                return filter;
+            }
+            else
+            {
+                return new Filter<KanbanSubscriber>().None();
+            }
+        }
+    }
+
     /// <summary>
     ///     Interaction logic for TaskPanel.xaml
     /// </summary>

+ 3 - 0
prs.desktop/Panels/Tasks/TasksByStatusControl.xaml

@@ -70,6 +70,9 @@
                           SelectionChanged="TaskTypes_SelectionChanged" VerticalContentAlignment="Center"
                           SelectedValuePath="Key" DisplayMemberPath="Value" />
                 <Button DockPanel.Dock="Left" x:Name="JobFilterBtn" Content="Filter Job" Padding="4,0" Margin="5,0,0,0" Click="JobFilterBtn_OnClick" />
+                <local:TaskPanelFilterButton DockPanel.Dock="Left" x:Name="FilterButton"
+                                             Margin="5,0,0,0"
+                                             OnFilterRefresh="FilterButton_OnFilterRefresh"/>
                 <Label DockPanel.Dock="Left" Content="Search" Margin="5,0,0,0" />
                 <Button DockPanel.Dock="Right" x:Name="Export" Padding="10,0" Margin="5,0,0,0" Content="Export"
                         Click="Export_Click" />

+ 20 - 9
prs.desktop/Panels/Tasks/TasksByStatusControl.xaml.cs

@@ -555,6 +555,11 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
     private string SearchText = "";
     private Guid SelectedType = CoreUtils.FullGuid;
 
+    private void FilterButton_OnFilterRefresh()
+    {
+        Refresh();
+    }
+
     private static Filter<T> GetSearchFilter<T>(Expression<Func<T, object?>> expression, string searchText) where T : Entity, new()
     {
         Filter<T>? result = null;
@@ -587,16 +592,19 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
         return filter;
     }
 
-    private Filter<Kanban> GetKanbanFilter()
+    private Filter<Kanban>? GetKanbanFilter()
     {
-        var filter = new Filter<Kanban>(x => x.Closed).IsEqualTo(DateTime.MinValue);
+        var filters = new Filters<Kanban>();
+
+        filters.Add(new Filter<Kanban>(x => x.Closed).IsEqualTo(DateTime.MinValue));
+        filters.Add(FilterButton.GetFilter());
 
         if (Host.Job != null)
         {
             if (Host.Job.ID != Guid.Empty)
-                filter = filter.And(x => x.JobLink.ID).IsEqualTo(Host.Job.ID);
+                filters.Add(new Filter<Kanban>(x => x.JobLink.ID).IsEqualTo(Host.Job.ID));
             else
-                filter = filter.And(x => x.JobLink.ID).None();
+                filters.Add(new Filter<Kanban>(x => x.JobLink.ID).None());
         }
 
         if (SelectedEmployee.ID != CoreUtils.FullGuid)
@@ -605,18 +613,18 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
             {
                 var empfilter = new Filter<Kanban>(x => x.EmployeeLink.ID).IsEqualTo(SelectedEmployee.ID)
                     .Or(x => x.ManagerLink.ID).IsEqualTo(SelectedEmployee.ID);
-                filter.Ands.Add(empfilter);
+                filters.Add(empfilter);
             }
             else
             {
-                filter = filter.And(x => x.EmployeeLink.ID).IsEqualTo(SelectedEmployee.ID);
+                filters.Add(new Filter<Kanban>(x => x.EmployeeLink.ID).IsEqualTo(SelectedEmployee.ID));
             }
         }
 
         if (SelectedEmployee.ID != App.EmployeeID)
-            filter = filter.And(x => x.Private).IsEqualTo(false);
+            filters.Add(new Filter<Kanban>(x => x.Private).IsEqualTo(false));
 
-        return filter;
+        return filters.Combine();
     }
 
     private void TaskTypesLabel_OnClick(object sender, RoutedEventArgs e)
@@ -760,8 +768,11 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
         IEnumerable<Kanban> kanbans;
         if (SelectedEmployee.ID != CoreUtils.FullGuid && SelectedEmployee.ID != Guid.Empty)
         {
+            var filter = new Filter<Kanban>(x => x.ID).InQuery(GetKanbanSubscriberFilter(), x => x.Kanban.ID);
+            filter.And(FilterButton.GetFilter() ?? new Filter<Kanban>().All());
+
             kanbans = Client.Query(
-                new Filter<Kanban>(x => x.ID).InQuery(GetKanbanSubscriberFilter(), x => x.Kanban.ID),
+                filter,
                 GetKanbanColumns().Cast<Kanban>(),
                 new SortOrder<Kanban>(x => x.DueDate) { Direction = SortDirection.Ascending }
             ).ToObjects<Kanban>();

+ 3 - 0
prs.desktop/Panels/Tasks/TasksByUserControl.xaml

@@ -126,6 +126,9 @@
                     Grid.Row="0"
                     Padding="5">
                     <DockPanel>
+                        <local:TaskPanelFilterButton DockPanel.Dock="Left"
+                                                     x:Name="FilterButton"
+                                                     OnFilterRefresh="TaskPanelFilterButton_OnFilterRefresh"/>
                         <Label DockPanel.Dock="Left" Content="Search" Margin="5,0,0,0" />
                         <Button DockPanel.Dock="Right" x:Name="Export" Padding="10,0" Margin="5,0,0,0" Content="Export"
                                 Click="Export_Click" />

+ 21 - 3
prs.desktop/Panels/Tasks/TasksByUserControl.xaml.cs

@@ -12,6 +12,7 @@ using System.Windows.Data;
 using System.Windows.Input;
 using System.Windows.Media.Imaging;
 using AvalonDock.Layout;
+using com.sun.org.apache.bcel.@internal.generic;
 using Comal.Classes;
 using InABox.Clients;
 using InABox.Core;
@@ -262,6 +263,11 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
 
     #region Filters 
 
+    private void TaskPanelFilterButton_OnFilterRefresh()
+    {
+        Refresh();
+    }
+
     private void IncludeCompleted_Checked(object sender, RoutedEventArgs e)
     {
         if (!IsReady)
@@ -302,6 +308,7 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
 
     #region Refresh
 
+
     private Filter<KanbanSubscriber> GetKanbanSubscriberFilter(Filter<KanbanSubscriber>? additional = null)
     {
         var filter = new Filter<KanbanSubscriber>(c => c.Kanban.Closed).IsEqualTo(DateTime.MinValue)
@@ -429,13 +436,20 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
     {
         filter = GetKanbanSubscriberFilter(filter);
 
+        var kanbanFilter = new Filter<Kanban>(x => x.ID).InQuery(filter, x => x.Kanban.ID);
+        var buttonFilter = FilterButton.GetFilter();
+        if(buttonFilter is not null)
+        {
+            kanbanFilter.And(buttonFilter);
+        }
+
         var results = Client.QueryMultiple(
             new KeyedQueryDef<KanbanSubscriber>(
                 filter,
                 new Columns<KanbanSubscriber>(x => x.ID, x => x.Employee.ID, x => x.Kanban.ID),
                 new SortOrder<KanbanSubscriber>(x => x.Kanban.DueDate) { Direction = SortDirection.Ascending }),
             new KeyedQueryDef<Kanban>(
-                new Filter<Kanban>(x => x.ID).InQuery(filter, x => x.Kanban.ID),
+               kanbanFilter,
                 GetKanbanColumns()));
 
         var kanbans = results.GetObjects<Kanban>().ToDictionary(x => x.ID);
@@ -444,9 +458,13 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
             if (kanbans.TryGetValue(x.Kanban.ID, out var kanban))
             {
                 x.Kanban.Synchronise(kanban);
+                return x;
+            }
+            else
+            {
+                return null;
             }
-            return x;
-        });
+        }).NotNull();
     }
 
     public void Refresh()