| 
					
				 | 
			
			
				@@ -18,10 +18,11 @@ using InABox.DynamicGrid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using InABox.WPF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Syncfusion.UI.Xaml.Kanban; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 using Syncfusion.Windows.Tools.Controls; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+using static com.sun.tools.javac.code.Symbol; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace PRSDesktop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class TasksByUserEmployeeHeader 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class TasksByUserEmployeeHeader : INotifyPropertyChanged 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public Guid EmployeeID { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -38,6 +39,21 @@ public class TasksByUserEmployeeHeader 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private TasksByUserModel Model; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public event PropertyChangedEventHandler? PropertyChanged; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Create the OnPropertyChanged method to raise the event 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // The calling member's name will be used as the parameter. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    protected void OnPropertyChanged([CallerMemberName] string? name = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (name.Equals(nameof(Tasks))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            OnPropertyChanged(nameof(NumTasks)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            OnPropertyChanged(nameof(NumHours)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public TasksByUserEmployeeHeader(Guid employeeID, string name, BitmapImage image, TasksByUserModel model) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         EmployeeID = employeeID; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -45,55 +61,84 @@ public class TasksByUserEmployeeHeader 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Image = image; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Model = model; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void UpdateTasks() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        OnPropertyChanged(nameof(Tasks)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public class TasksByUserEmployeeCategory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public Guid EmployeeID { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public List<TaskModel> Tasks { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public string Category { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public SuspendableObservableCollection<TaskModel> Tasks { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public TasksByUserEmployeeCategory(Guid employeeID) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public TasksByUserEmployeeCategory(Guid employeeID, string category) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         EmployeeID = employeeID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Category = category; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class TasksByUserCategory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class TasksByUserCategory : INotifyPropertyChanged 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private bool _collapsed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public bool Collapsed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        get => _collapsed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        set 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _collapsed = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            OnPropertyChanged(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public string Category { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public IEnumerable<TasksByUserEmployeeCategory> EmployeeCategories => EmployeeCategoryDictionary.Values; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public Dictionary<Guid, TasksByUserEmployeeCategory> EmployeeCategoryDictionary { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public TasksByUserCategory(string category) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public TasksByUserCategory(string category, bool collapsed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Category = category; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Collapsed = collapsed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public event PropertyChangedEventHandler? PropertyChanged; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Create the OnPropertyChanged method to raise the event 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // The calling member's name will be used as the parameter. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    protected void OnPropertyChanged([CallerMemberName] string? name = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public class TasksByUserModel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public List<TasksByUserEmployeeHeader> SectionHeaders { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public SuspendableObservableCollection<TasksByUserEmployeeHeader> SectionHeaders { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public List<TasksByUserCategory> Categories { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public SuspendableObservableCollection<TasksByUserCategory> Categories { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, ITaskControl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private static readonly BitmapImage anonymous = PRSDesktop.Resources.anonymous.AsBitmapImage(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public TasksByUserModel Model { get; set; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public TasksByUserModel Model { get; set; } = new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private ILookup<Guid, Guid> TeamEmployees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private Dictionary<Guid, EmployeeModel> Employees; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private KanbanViewMode _mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private bool bPopulating; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private KanbanViewMode _mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     public KanbanViewMode Mode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         get => _mode; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -154,7 +199,7 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SelectedTeams.ItemsSource = teams; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         foreach (var team in Host.KanbanSettings.UserSettings.SelectedTeams) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            SelectedTeams.SelectedItems.Add(teams.Where(x => x.Key == team)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            SelectedTeams.SelectedItems.Add(teams.FirstOrDefault(x => x.Key == team)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -169,7 +214,7 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             SelectedEmployees.ItemsSource = Employees.Where(x => availableemployees.Contains(x.Key)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             SelectedEmployees.SelectedItems.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            foreach (var employee in Host.KanbanSettings.UserSettings.SelectedEmployees.Where(x => availableemployees.Contains(x))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            foreach (var employee in Host.KanbanSettings.UserSettings.SelectedEmployees.Where(availableemployees.Contains)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 SelectedEmployees.SelectedItems.Add(Employees.FirstOrDefault(x => Equals(x.Key, employee))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         catch (Exception e) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -207,16 +252,54 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         LoadEmployees(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         PopulateEmployees(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Mode = Host.KanbanSettings.StatusSettings.CompactView ? KanbanViewMode.Compact : KanbanViewMode.Full; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Mode = Host.KanbanSettings.UserSettings.CompactView ? KanbanViewMode.Compact : KanbanViewMode.Full; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         PopulateKanbanTypes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #endregion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #region Filters  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void IncludeCompleted_Checked(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!IsReady) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SaveSettings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Refresh(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void IncludeObserved_Checked(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!IsReady) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SaveSettings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Refresh(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void IncludeManaged_Checked(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!IsReady) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SaveSettings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Refresh(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void TaskType_SelectionChanged(object sender, SelectionChangedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FilterKanbans(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void Search_KeyUp(object sender, KeyEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FilterKanbans(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #endregion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #region Refresh 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private Filter<KanbanSubscriber> GetKanbanSubscriberFilter() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private Filter<KanbanSubscriber> GetKanbanSubscriberFilter(Filter<KanbanSubscriber>? additional = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         var filter = new Filter<KanbanSubscriber>(c => c.Kanban.Closed).IsEqualTo(DateTime.MinValue) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             .And(x => x.Kanban.Locked).IsEqualTo(false); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -249,82 +332,138 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 filter = filter.And(x => x.Assignee).IsEqualTo(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return filter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (additional is not null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return additional.And(filter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return filter; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private void ReloadColumns() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Model.SectionHeaders.SupressNotification = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Model.SectionHeaders.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        foreach (var employeeID in Host.KanbanSettings.UserSettings.SelectedEmployees) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var emps = Host.KanbanSettings.UserSettings.SelectedEmployees.OrderBy(x => Employees[x].Name).ToArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        foreach (var employeeID in emps) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (Employees.TryGetValue(employeeID, out var employee)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 Model.SectionHeaders.Add(new TasksByUserEmployeeHeader(employeeID, employee.Name, employee.Image ?? anonymous, Model)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Model.SectionHeaders.SupressNotification = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Model.Categories.SupressNotification = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var oldCategories = Model.Categories.ToDictionary(x => x.Category); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Model.Categories.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        foreach (var category in _categoryOrder) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (category.Equals(Kanban.COMPLETE) && !Host.KanbanSettings.UserSettings.IncludeCompleted) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var newCategory = new TasksByUserCategory(category, oldCategories.GetValueOrDefault(category)?.Collapsed ?? false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            foreach (var employeeID in emps) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (Employees.TryGetValue(employeeID, out var employee)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var cat = new TasksByUserEmployeeCategory(employeeID, category); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    newCategory.EmployeeCategoryDictionary[employeeID] = cat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    var header = Model.SectionHeaders.First(x => x.EmployeeID == employeeID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    cat.Tasks.CollectionChanged += (s, e) => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        header.UpdateTasks(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Model.Categories.Add(newCategory); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Model.Categories.SupressNotification = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public void Refresh() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var categoryOrder = new Dictionary<string, int> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static readonly string[] _categoryOrder = new[] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.OPEN, 0 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.INPROGRESS, 1 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.WAITING, 2 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.COMPLETE, 3 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Kanban.OPEN, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Kanban.INPROGRESS, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Kanban.WAITING, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Kanban.COMPLETE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var filter = GetKanbanSubscriberFilter(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private Columns<Kanban> GetKanbanColumns() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return new Columns<Kanban>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.DueDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Completed, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Description, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Summary, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Category, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.EmployeeLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.EmployeeLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.ManagerLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.ManagerLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Notes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Title, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.JobLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.JobLink.JobNumber, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.JobLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Type.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Type.Code, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Attachments, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.Locked, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x => x.EstimatedTime); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private IEnumerable<KanbanSubscriber> LoadSubscribers(Filter<KanbanSubscriber>? filter = null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        filter = GetKanbanSubscriberFilter(filter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        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), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                GetKanbanColumns())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var kanbans = results.GetObjects<Kanban>().ToDictionary(x => x.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return results.GetObjects<KanbanSubscriber>().Select(x => 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (kanbans.TryGetValue(x.Kanban.ID, out var kanban)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                x.Kanban.Synchronise(kanban); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public void Refresh() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         using (new WaitCursor()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var kanbans = new Client<KanbanSubscriber>().Query( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                filter, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                new Columns<KanbanSubscriber> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.DueDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Completed, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    //x => x.Kanban.Description, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Summary, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Category, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.EmployeeLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.EmployeeLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.ManagerLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.ManagerLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Notes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Title, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.JobLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.JobLink.JobNumber, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.JobLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Type.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Type.Code, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Attachments, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.Locked, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Employee.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    x => x.Kanban.EstimatedTime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                new SortOrder<KanbanSubscriber>(x => x.Kanban.DueDate) { Direction = SortDirection.Ascending } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var models = CreateModels(kanbans.ToObjects<KanbanSubscriber>()).ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var models = CreateModels(LoadSubscribers()).ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ReloadColumns(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            AllTasks = models.OrderBy(x => categoryOrder[x.Category]).ThenBy(x => x.DueDate).ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            AllTasks = models.OrderBy(x => x.DueDate).ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             FilterKanbans(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// <summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Take the full list of kanbans loaded from the database, and filter based on the search UI elements, filtering into the columns. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// </summary> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private void FilterKanbans() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var categoryOrder = new Dictionary<string, int> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.OPEN, 0 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.INPROGRESS, 1 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.WAITING, 2 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                { Kanban.COMPLETE, 3 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         IEnumerable<TaskModel> filtered = AllTasks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (TaskType.SelectedItem is KanbanType kanbanType) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -336,30 +475,31 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             filtered = filtered.Where(x => x.Search(searches)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var categories = new Dictionary<string, TasksByUserCategory>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        foreach (var task in filtered) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var categoryMap = Model.Categories.ToDictionary(x => x.Category, x => x.EmployeeCategoryDictionary); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        foreach(var category in Model.Categories) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if(!categories.TryGetValue(task.Category, out var category)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            foreach(var empCat in category.EmployeeCategories) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                category = new TasksByUserCategory(task.Category); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                categories.Add(task.Category, category); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                empCat.Tasks.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if(!category.EmployeeCategoryDictionary.TryGetValue(task.EmployeeCategory, out var employeeCategory)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                employeeCategory = new TasksByUserEmployeeCategory(task.EmployeeCategory); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                category.EmployeeCategoryDictionary.Add(task.EmployeeCategory, employeeCategory); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        SelectedTasks.Clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            employeeCategory.Tasks.Add(task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (task.Checked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        foreach (var task in filtered) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(categoryMap.TryGetValue(task.Category, out var categoryDict)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                SelectedTasks.Add(task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (categoryDict.TryGetValue(task.EmployeeCategory, out var employeeCategory)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    employeeCategory.Tasks.Add(task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (task.Checked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        SelectedTasks.Add(task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Model.Categories.AddRange(categories.Values.OrderBy(x => categoryOrder[x.Category])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private IEnumerable<TaskModel> CreateModels(IEnumerable<KanbanSubscriber> subscribers) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -367,26 +507,31 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         foreach(var subscriber in subscribers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var kanban = subscriber.Kanban; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var empValid = Entity.IsEntityLinkValid<KanbanSubscriber, EmployeeLink>(x => x.Kanban.EmployeeLink, row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var mgrValid = Entity.IsEntityLinkValid<KanbanSubscriber, EmployeeLink>(x => x.Kanban.ManagerLink, row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var completed = row.Get<KanbanSubscriber, DateTime>(e => e.Kanban.Completed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var locked = row.Get<KanbanSubscriber, bool>(e => e.Kanban.Locked); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var typeID = row.Get<KanbanSubscriber, Guid>(e => e.Kanban.Type.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var typeCode = row.Get<KanbanSubscriber, string>(e => e.Kanban.Type.Code); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var job = row.Get<KanbanSubscriber, string>(x => x.Kanban.JobLink.JobNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var model = new TaskModel(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Title = kanban.Title; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.ID = kanban.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Description = kanban.Summary ?? ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.EmployeeCategory = subscriber.Employee.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Category = kanban.Category; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (model.Category.IsNullOrWhiteSpace()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                model.Category = "Open"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var model = new TaskModel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Title = kanban.Title, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ID = kanban.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Description = kanban.Summary ?? "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                EmployeeCategory = subscriber.Employee.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Category = kanban.Category.NotWhiteSpaceOr("Open"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Attachments = kanban.Attachments > 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                DueDate = kanban.DueDate, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                CompletedDate = kanban.Completed, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Locked = kanban.Locked, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                EstimatedTime = kanban.EstimatedTime, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                EmployeeID = kanban.EmployeeLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ManagerID = kanban.ManagerLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                JobID = kanban.JobLink.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                JobNumber = kanban.JobLink.JobNumber?.Trim() ?? "", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                JobName = kanban.JobLink.Name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Type = new KanbanType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    ID = kanban.Type.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    Code = kanban.Type.Code 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Number = kanban.Number, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Checked = SelectedTasks.Any(x => x.ID == kanban.ID) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var colour = subscriber.Employee.ID == kanban.EmployeeLink.ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 ? TaskModel.KanbanColor( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -401,12 +546,6 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             model.Color = System.Windows.Media.Color.FromArgb(colour.A, colour.R, colour.G, colour.B); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Attachments = kanban.Attachments > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.DueDate = kanban.DueDate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.CompletedDate = kanban.Completed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Locked = kanban.Locked; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.EstimatedTime = kanban.EstimatedTime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var notes = new List<List<string>> { new() }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             var kanbanNotes = kanban.Notes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if (kanbanNotes != null) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -425,36 +564,27 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             model.Notes = string.Join("\n===================================\n", notes.Reverse<List<string>>().Select(x => string.Join('\n', x))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.EmployeeID = kanban.EmployeeLink.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.ManagerID = kanban.ManagerLink.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var employeeString = kanban.EmployeeLink.ID == subscriber.Employee.ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ? "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                : kanban.EmployeeLink.ID == Guid.Empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    ? " to (Unallocated)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    : " to " + kanban.EmployeeLink.Name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            SetTaskModelAssignedTo(model, kanban, subscriber.Employee.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var managerString = kanban.ManagerLink.ID == Guid.Empty || kanban.ManagerLink.ID == subscriber.Employee.ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ? "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                : " by " + kanban.ManagerLink.Name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            yield return model; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.AssignedTo = !string.IsNullOrEmpty(employeeString) || !managerString.IsNullOrWhiteSpace() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ? $"Assigned{employeeString}{managerString}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                : ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private static void SetTaskModelAssignedTo(TaskModel model, IKanban kanban, Guid subscriberID) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var employeeString = kanban.EmployeeLink.ID == subscriberID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ? "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            : kanban.EmployeeLink.ID == Guid.Empty 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ? " to (Unallocated)" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                : " to " + kanban.EmployeeLink.Name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.JobID = kanban.JobLink.ID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.JobNumber = kanban.JobLink.JobNumber?.Trim() ?? ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.JobName = kanban.JobLink.Name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Checked = SelectedTasks.Any(x => x.ID == model.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Type = new KanbanType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ID = typeID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Code = typeCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            model.Number = kanban.Number; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var managerString = kanban.ManagerLink.ID == Guid.Empty || kanban.ManagerLink.ID == subscriberID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ? "" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            : " by " + kanban.ManagerLink.Name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            yield return model; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        model.AssignedTo = !string.IsNullOrEmpty(employeeString) || !managerString.IsNullOrWhiteSpace() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ? $"Assigned{employeeString}{managerString}" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            : ""; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #endregion 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -502,6 +632,85 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         e.CanExecute = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void ItemsControl_DragOver(object sender, DragEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sender is not FrameworkElement element || element.Tag is not TasksByUserEmployeeCategory category) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        e.Effects = DragDropEffects.None; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (e.Data.GetDataPresent(typeof(TaskModel))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var model = e.Data.GetData(typeof(TaskModel)) as TaskModel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (model is not null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                && (model.Category != category.Category || model.EmployeeCategory != category.EmployeeID) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                && !SelectedTasks.Any(x => x.Locked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                && SelectedTasks.Concat(CoreUtils.One(model)).Any(x => x.IsAssignee)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                e.Effects = DragDropEffects.Move; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void ItemsControl_Drop(object sender, DragEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sender is not FrameworkElement element || element.Tag is not TasksByUserEmployeeCategory category) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (e.Data.GetDataPresent(typeof(TaskModel))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var models = SelectedModels(e.Data.GetData(typeof(TaskModel)) as TaskModel) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .Where(x => (!x.Category.Equals(category.Category) || x.EmployeeID != category.EmployeeID) && x.IsAssignee) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .ToList(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!models.Any()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var changingCategory = models.Any(x => !x.Category.Equals(category.Category)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var completing = changingCategory && category.Category.Equals(Kanban.COMPLETE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var completed = DateTime.Now; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (completing) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (MessageBox.Show($"Are you sure you want to complete the selected tasks?", "Confirm Completion", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        MessageBoxButton.YesNo) != MessageBoxResult.Yes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var kanbans = Host.LoadKanbans(models, new Columns<Kanban>(x => x.ID, x => x.EmployeeLink.ID, x => x.Private, x => x.Number)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var subscribers = new ClientKanbanSubscriberSet(kanbans.Select(x => x.ID)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            foreach(var kanban in kanbans) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!kanban.Private) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    kanban.EmployeeLink.ID = category.EmployeeID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    subscribers.EnsureAssignee(kanban.ID, kanban.EmployeeLink.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    kanban.Category = category.Category; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if (completing) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        kanban.Completed = completed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    MessageBox.Show($"Cannot change assignee for task {kanban.Number} because it is private."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    models.RemoveAll(x => x.ID == kanban.ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Client.Save(kanbans.Where(x => x.IsChanged()), $"Task Employee Updated"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            subscribers.Save(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var kanbanIDs = models.Select(x => x.ID).ToArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            AllTasks.RemoveAll(x => kanbanIDs.Contains(x.ID)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            AllTasks.AddRange(CreateModels(LoadSubscribers(new Filter<KanbanSubscriber>(x => x.Kanban.ID).InList(kanbanIDs)))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            AllTasks.Sort((x, y) => x.DueDate.CompareTo(y.DueDate)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            FilterKanbans(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #endregion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #region ITaskControl 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -550,7 +759,7 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         var teams = SelectedTeams.SelectedItems.Select(x => ((KeyValuePair<Guid, string>)x).Key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Host.KanbanSettings.UserSettings.SelectedTeams = teams.ToArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var emps = SelectedEmployees.SelectedItems.Select(x => ((KeyValuePair<Guid, string>)x).Key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var emps = SelectedEmployees.SelectedItems.Select(x => ((KeyValuePair<Guid, EmployeeModel>)x).Key); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         emps = emps.Where(e => TeamEmployees.Any(t => t.Contains(e))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Host.KanbanSettings.UserSettings.SelectedEmployees = emps.ToArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -584,58 +793,59 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SaveSettings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void EmployeesSelectionChanged(object sender, SelectionChangedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void SelectedEmployees_ItemChecked(object sender, ItemCheckedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!IsReady || bPopulating) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!IsReady || bPopulating || sender != SelectedEmployees) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         SaveSettings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Refresh(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    #endregion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void Export_Click(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void IncludeCompleted_Checked(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void IncludeObserved_Checked(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void IncludeManaged_Checked(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private void ViewType_SelectionChanged(object sender, SelectionChangedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Mode = ViewType.SelectedIndex switch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            0 => KanbanViewMode.Full, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            1 => KanbanViewMode.Compact, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            _ => KanbanViewMode.Full 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (IsReady) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Host.KanbanSettings.UserSettings.CompactView = Mode == KanbanViewMode.Compact; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Host.SaveSettings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void TaskType_SelectionChanged(object sender, SelectionChangedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #endregion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void Search_KeyUp(object sender, KeyEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void Export_Click(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var form = new DynamicExportForm(typeof(Kanban), GetKanbanColumns().ColumnNames()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (form.ShowDialog() != true) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var export = Client.Query( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            new Filter<Kanban>(x => x.ID).InQuery(GetKanbanSubscriberFilter(), x => x.Kanban.ID), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            new Columns<Kanban>(form.Fields), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            LookupFactory.DefineSort<Kanban>() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void ItemsControl_DragOver(object sender, DragEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var employee = "Tasks for " + string.Join(',', Employees.Where(x => Host.KanbanSettings.UserSettings.SelectedEmployees.Contains(x.Key)).Select(x => x.Value.Name)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ExcelExporter.DoExport<Kanban>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            export, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string.Format( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                "{0} ({1:dd-MMM-yy})", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                employee, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                DateTime.Today 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private void ItemsControl_Drop(object sender, DragEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private void FoldButton_Click(object sender, RoutedEventArgs e) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sender is not FrameworkElement element || element.Tag is not TasksByUserCategory category) return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        category.Collapsed = !category.Collapsed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |