Przeglądaj źródła

Persisting Kanban screen filters and selected employees. Fixed image refresh issue with empty images.

Kenric Nugteren 1 rok temu
rodzic
commit
3910c4f72c

+ 0 - 104
prs.classes/Settings/KanbanSettings.cs

@@ -1,104 +0,0 @@
-using System;
-using InABox.Configuration;
-using InABox.Core;
-
-namespace Comal.Classes
-{
-    public enum KanbanViewType
-    {
-        Status,
-        User,
-        Planner,
-        List
-    }
-
-    public abstract class KanbanSettingsSection
-    {
-    }
-
-    public abstract class KanbanCardSettings : KanbanSettingsSection
-    {
-        public KanbanCardSettings()
-        {
-            CompactView = false;
-            IncludeCompleted = false;
-            IncludeObserved = true;
-        }
-
-        public bool CompactView { get; set; }
-        public bool IncludeCompleted { get; set; }
-        public bool IncludeObserved { get; set; }
-    }
-
-    public class KanbanStatusSettings : KanbanCardSettings
-    {
-        public KanbanStatusSettings()
-        {
-            SelectedEmployee = Guid.Empty;
-            SelectedType = CoreUtils.FullGuid;
-            IncludeLocked = true;
-        }
-
-        public Guid SelectedEmployee { get; set; }
-        public Guid SelectedType { get; set; }
-
-        public bool IncludeLocked { get; set; }
-    }
-
-    public class KanbanUserSettings : KanbanCardSettings
-    {
-        public KanbanUserSettings()
-        {
-            TeamsHeight = 200.0F;
-            AnchorWidth = 300.0F;
-            SelectedTeams = new Guid[] { };
-            SelectedEmployees = new Guid[] { };
-            IncludeManaged = false;
-        }
-
-        public double AnchorWidth { get; set; }
-        public double TeamsHeight { get; set; }
-        public Guid[] SelectedTeams { get; set; }
-        public Guid[] SelectedEmployees { get; set; }
-        public bool IncludeManaged { get; set; }
-    }
-
-    public class KanbanPlannerSettings : KanbanSettingsSection
-    {
-        public KanbanPlannerSettings()
-        {
-            SelectedType = CoreUtils.FullGuid;
-            IncludeCompleted = false;
-        }
-
-        public Guid SelectedType { get; set; }
-        public bool IncludeCompleted { get; set; }
-    }
-
-    public class KanbanListSettings : KanbanSettingsSection
-    {
-    }
-
-    public class KanbanSettings : IUserConfigurationSettings
-    {
-        public KanbanSettings()
-        {
-            ViewType = KanbanViewType.Status;
-
-            StatusSettings = new KanbanStatusSettings();
-            UserSettings = new KanbanUserSettings();
-            PlannerSettings = new KanbanPlannerSettings();
-            ListSettings = new KanbanListSettings();
-        }
-
-        public KanbanViewType ViewType { get; set; }
-
-        public KanbanStatusSettings StatusSettings { get; set; }
-
-        public KanbanUserSettings UserSettings { get; set; }
-
-        public KanbanPlannerSettings PlannerSettings { get; set; }
-
-        public KanbanListSettings ListSettings { get; set; }
-    }
-}

+ 1 - 4
prs.desktop/Components/EquipmentSelector/EquipmentSelector.xaml.cs

@@ -167,12 +167,9 @@ namespace PRSDesktop
                 foreach (var row in groups.Rows)
                 {
                     var image = Images.FirstOrDefault(x => x.ID.Equals(row.Get<EquipmentGroup,Guid>(c=>c.Thumbnail.ID)));
-                    BitmapImage img =  (image != null && image.Data != null && image.Data.Length > 0)
-                        ? ImageUtils.LoadImage(image.Data)
-                        : PRSDesktop.Resources.truck.AsBitmapImage();
                     var grp = _groups.FirstOrDefault(x => x.Key == row.Get<EquipmentGroup, Guid>(c => c.Thumbnail.ID));
                     if (grp != null)
-                        grp.Image = img;
+                        grp.Image = ImageUtils.LoadImage(image.Data) ?? PRSDesktop.Resources.truck.AsBitmapImage();
                 }
                 
                 ObservableCollection<ListEntry> groupdata = new() { new ListEntry(Guid.Empty, "All Equipment", PRSDesktop.Resources.truck.AsBitmapImage()) };

+ 2 - 0
prs.desktop/Forms/DesktopConsole.cs

@@ -22,6 +22,8 @@ public class DesktopConsole : Console
     {
         base.OnLoaded();
 
+        ConsoleControl.Enabled = true;
+
         logger = new EventLogger(OnLog);
         MainLogger.AddLogger(logger);
     }

+ 1 - 1
prs.desktop/Panels/Attendance/AttendanceKanban.cs

@@ -8,7 +8,7 @@ namespace PRSDesktop
     public class AttendanceKanban : KanbanModel
     {
         public string Name { get; set; }
-        public BitmapImage Image { get; set; }
+        public BitmapImage? Image { get; set; }
         public string Clockin { get; set; }
         public string Clockout { get; set; }
         public string Address { get; set; }

+ 1 - 6
prs.desktop/Panels/Attendance/AttendancePanel.xaml.cs

@@ -508,12 +508,7 @@ namespace PRSDesktop
                         var kanban = Kanbans.FirstOrDefault(x => string.Equals(x.ID, empid.ToString()));
                         if (kanban != null)
                         {
-                            if (img == null)
-                            {
-                                img = new BitmapImage();
-                                img.LoadImage(row.Get<Document, byte[]>(c => c.Data));
-                            }
-
+                            img ??= ImageUtils.LoadImage(docData);
                             kanban.Image = img;
                         }
                     }

+ 1 - 3
prs.desktop/Panels/Equipment/EquipmentPanel.xaml.cs

@@ -95,9 +95,7 @@ namespace PRSDesktop
             foreach (var row in groups.Rows)
             {
                 var image = Images.FirstOrDefault(x => x.ID.Equals(row.Get<EquipmentGroup,Guid>(c=>c.Thumbnail.ID)));
-                BitmapImage img =  (image != null && image.Data != null && image.Data.Length > 0)
-                    ? ImageUtils.LoadImage(image.Data)
-                    : PRSDesktop.Resources.specifications.AsBitmapImage();
+                var img = ImageUtils.LoadImage(image?.Data) ?? PRSDesktop.Resources.specifications.AsBitmapImage();
 
                 GroupList.Add(
                     new Tuple<string, Guid, BitmapImage>(

+ 10 - 10
prs.desktop/Panels/Jobs/DocumentSets/JobDocumentSetPanel.xaml.cs

@@ -223,20 +223,20 @@ namespace PRSDesktop
                 );
                 preview.ItemsSource = files.Rows
                     .Select(r =>
-                        new Tuple<Guid, String, BitmapImage, JobDocumentSetMileStoneFile>(
+                    {
+                        var thumbnailData = r.Get<JobDocumentSetMileStoneFile, byte[]?>(c => c.Thumbnail);
+                        var image = ImageUtils.LoadImage(thumbnailData);
+                        return new Tuple<Guid, String, BitmapImage, JobDocumentSetMileStoneFile>(
                             r.Get<JobDocumentSetMileStoneFile, Guid>(c => c.ID),
                             r.Get<JobDocumentSetMileStoneFile, String>(c => c.DocumentLink.FileName),
-                            r.Get<JobDocumentSetMileStoneFile, byte[]>(c => c.Thumbnail) != null
-                                ? String.IsNullOrWhiteSpace(block.Watermark)
-                                    ? ImageUtils.LoadImage(r.Get<JobDocumentSetMileStoneFile, byte[]>(c => c.Thumbnail))
-                                    : ImageUtils.LoadImage(r.Get<JobDocumentSetMileStoneFile, byte[]>(c => c.Thumbnail))
-                                        .AsBitmap().WatermarkImage(block.Watermark, Color.LightSalmon)
-                                        .AsBitmapImage()
+                            image != null
+                                ? block.Watermark.IsNullOrWhiteSpace()
+                                    ? image
+                                    : image.AsBitmap().WatermarkImage(block.Watermark, Color.LightSalmon).AsBitmapImage()
                                 : ImageUtils.BitmapFromColor(Color.White, 256, 192, Color.Transparent)
                                     .WatermarkImage("No Preview\nAvailable", Color.LightGray).AsBitmapImage(),
-                            r.ToObject<JobDocumentSetMileStoneFile>()
-                        )
-                    ).ToList();
+                            r.ToObject<JobDocumentSetMileStoneFile>());
+                    }).ToList();
             }
             else
                 preview.ItemsSource = new List<Tuple<Guid, String, BitmapImage, JobDocumentSetMileStoneFile>>();

+ 0 - 1
prs.desktop/Panels/Jobs/Requisitions/JobRequisitionGrid.cs

@@ -115,7 +115,6 @@ namespace PRSDesktop
             }
             Progress.Close();
             var page = new TaskGrid();
-            page.MyID = App.EmployeeID;
             page.OnAfterSave += (form, items) =>
             {
                 KanbanAfterSave(form, items.Cast<Kanban>().ToArray());

+ 1 - 10
prs.desktop/Panels/Manufacturing/ManufacturingPanel.xaml.cs

@@ -168,16 +168,7 @@ namespace PRSDesktop
                 {
                     var image = FactoryImages.FirstOrDefault(x => x.ID.Equals(Factory.Thumbnail.ID));
 
-                    BitmapImage img;
-                    if (image != null && image.Data != null && image.Data.Length > 0)
-                    {
-                        img = new BitmapImage();
-                        img.LoadImage(image.Data);
-                    }
-                    else
-                    {
-                        img = PRSDesktop.Resources.factory.AsBitmapImage();
-                    }
+                    var img = ImageUtils.LoadImage(image?.Data) ?? PRSDesktop.Resources.factory.AsBitmapImage();
 
                     FactorySource.Add(new Tuple<string, BitmapImage, Guid>(Factory.Name, img, Factory.ID));
                     if (settings.FactoryID == Factory.ID)

+ 0 - 1
prs.desktop/Panels/Staging/StagingPanel.xaml.cs

@@ -587,7 +587,6 @@ public class Module
             task.ManagerLink.ID = App.EmployeeID;
 
             var page = new TaskGrid();
-            page.MyID = App.EmployeeID;
 
             if (page.EditItems(new[] { task }))
             {

+ 68 - 0
prs.desktop/Panels/Tasks/KanbanSettings.cs

@@ -0,0 +1,68 @@
+using System;
+using InABox.Configuration;
+using InABox.Core;
+using InABox.DynamicGrid;
+
+namespace PRSDesktop;
+
+public enum KanbanViewType
+{
+    Status,
+    User,
+    Planner,
+    List
+}
+
+public abstract class KanbanSettingsSection
+{
+}
+
+public abstract class KanbanCardSettings : KanbanSettingsSection
+{
+    public bool CompactView { get; set; } = false;
+    public bool IncludeCompleted { get; set; } = false;
+    public bool IncludeObserved { get; set; } = true;
+}
+
+public class KanbanStatusSettings : KanbanCardSettings
+{
+    public Guid SelectedEmployee { get; set; } = Guid.Empty;
+
+    public Guid SelectedType { get; set; } = CoreUtils.FullGuid;
+
+    public bool IncludeLocked { get; set; } = true;
+}
+
+public class KanbanUserSettings : KanbanCardSettings
+{
+    public double AnchorWidth { get; set; } = 300.0F;
+    public double TeamsHeight { get; set; } = 200.0F;
+    public Guid[] SelectedTeams { get; set; } = Array.Empty<Guid>();
+    public Guid[] SelectedEmployees { get; set; } = Array.Empty<Guid>();
+    public bool IncludeManaged { get; set; } = false;
+}
+
+public class KanbanPlannerSettings : KanbanSettingsSection
+{
+    public Guid SelectedType { get; set; } = CoreUtils.FullGuid;
+    public bool IncludeCompleted { get; set; } = false;
+}
+
+public class KanbanListSettings : KanbanSettingsSection
+{
+}
+
+public class KanbanSettings : IUserConfigurationSettings
+{
+    public DynamicGridSelectedFilterSettings Filters { get; set; } = new();
+
+    public KanbanViewType ViewType { get; set; } = KanbanViewType.Status;
+
+    public KanbanStatusSettings StatusSettings { get; set; } = new();
+
+    public KanbanUserSettings UserSettings { get; set; } = new();
+
+    public KanbanPlannerSettings PlannerSettings { get; set; } = new();
+
+    public KanbanListSettings ListSettings { get; set; } = new();
+}

+ 8 - 29
prs.desktop/Panels/Tasks/TaskGrid.cs

@@ -20,8 +20,6 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
         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);       
 
         OnCustomiseEditor += CustomiseEditor;
         OnBeforeSave += BeforeSave;
@@ -34,8 +32,6 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
         options.AddRange(DynamicGridOption.SelectColumns, DynamicGridOption.FilterRows, DynamicGridOption.RecordCount);
     }
 
-    public Guid MyID { get; set; } = CoreUtils.FullGuid;
-
     private bool FormMenuClick(CoreRow? row)
     {
         if (row is null)
@@ -62,7 +58,7 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
         switch (column.ColumnName)
         {
             case "Private":
-                enabled = kanban.EmployeeLink.ID == MyID && kanban.ManagerLink.ID == MyID;
+                enabled = kanban.EmployeeLink.ID == App.EmployeeID && kanban.ManagerLink.ID == App.EmployeeID;
                 break;
             case "Description":
                 enabled = kanban.ID == Guid.Empty || (bFullControl && !kanban.Private);
@@ -90,7 +86,7 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
     {
         foreach (var kanban in kanbans)
         {
-            if (!MyID.Equals(kanban.ManagerLink.ID) && !MyID.Equals(kanban.EmployeeLink.ID))
+            if (!App.EmployeeID.Equals(kanban.ManagerLink.ID) && !App.EmployeeID.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.
@@ -117,25 +113,6 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
         }
     }
 
-    protected override void AfterLoad(IDynamicEditorForm editor, Kanban[] kanbans)
-    {
-        base.AfterLoad(editor, kanbans);
-        //EnsureAssignee(editor, kanbans.FirstOrDefault());
-        //EnsureAllocator(editor, kanbans.FirstOrDefault());
-
-        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);
-        }
-
-        //if (kanbans.FirstOrDefault().ID == Guid.Empty)
-        //    ReloadForms<Kanban, KanbanForm, KanbanTypeForm>(editor, kanbans.FirstOrDefault(), x => x.Type.ID, kanbans.FirstOrDefault().Type.ID);
-    }
-
     protected override Dictionary<string, object?> EditorValueChanged(IDynamicEditorForm editor, Kanban[] items, string name, object value)
     {
         var result = base.EditorValueChanged(editor, items, name, value);
@@ -168,13 +145,13 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
             managerEditor.IsEnabled = enabled;
             if (!enabled)
             {
-                employeeEditor.SetValue(employeeEditor.ColumnName, MyID);
-                managerEditor.SetValue(managerEditor.ColumnName, MyID);
+                employeeEditor.SetValue(employeeEditor.ColumnName, App.EmployeeID);
+                managerEditor.SetValue(managerEditor.ColumnName, App.EmployeeID);
 
                 foreach(var item in items)
                 {
-                    item.EmployeeLink.ID = MyID;
-                    item.ManagerLink.ID = MyID;
+                    item.EmployeeLink.ID = App.EmployeeID;
+                    item.ManagerLink.ID = App.EmployeeID;
                 }
             }
         }
@@ -250,6 +227,8 @@ public class TaskGrid : DynamicDataGrid<Kanban>, ITaskControl, IDefaultGrid
 
     public void Setup()
     {
+        FilterComponent.SetSettings(Host.KanbanSettings.Filters, false);
+
         Refresh(true, false);
     }
 

+ 2 - 1
prs.desktop/Panels/Tasks/TasksByStatusControl.xaml

@@ -72,7 +72,8 @@
                 <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"/>
+                                             OnFilterRefresh="FilterButton_OnFilterRefresh"
+                                             OnFiltersSelected="FilterButton_OnFiltersSelected"/>
                 <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" />

+ 13 - 5
prs.desktop/Panels/Tasks/TasksByStatusControl.xaml.cs

@@ -174,6 +174,7 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
         SetupKanbanTypesLookup(kanbanTypesTask.Result);
 
         Mode = Host.KanbanSettings.StatusSettings.CompactView ? KanbanViewMode.Compact : KanbanViewMode.Full;
+        FilterButton.SetSettings(Host.KanbanSettings.Filters, false);
     }
 
     private void SetupToolbar()
@@ -348,7 +349,7 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
                 .Select(e => e.ThumbnailID)
                 .Where(x => x != Guid.Empty).ToArray();
             EmployeeList.ItemsSource = Employees;
-            SelectedEmployee = Employees.First();
+            SelectedEmployee = Employees.FirstOrDefault(x => x.ID == Host.KanbanSettings.StatusSettings.SelectedEmployee) ?? Employees.First();
             EmployeeList.SelectedItem = SelectedEmployee;
             if (thumbnails.Any())
                 new Client<Document>().Query(
@@ -366,7 +367,7 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
         {
             EmployeeListColumn.Width = new GridLength(0.0F, GridUnitType.Pixel);
             EmployeeList.ItemsSource = Employees;
-            SelectedEmployee = Employees.First();
+            SelectedEmployee = Employees.FirstOrDefault(x => x.ID == Host.KanbanSettings.StatusSettings.SelectedEmployee) ?? Employees.First();
             EmployeeList.SelectedItem = SelectedEmployee;
         }
     }
@@ -382,15 +383,14 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
                 var model = Employees.FirstOrDefault(x => x.ThumbnailID.Equals(id));
                 if (model != null)
                 {
-                    model.Image = new BitmapImage();
-                    model.Image.LoadImage(row.Get<Document, byte[]>(x => x.Data));
+                    model.Image = ImageUtils.LoadImage(row.Get<Document, byte[]>(x => x.Data));
                 }
             }
 
             _updatingEmployees = true;
             EmployeeList.ItemsSource = null;
             EmployeeList.ItemsSource = Employees;
-            SelectedEmployee = Employees.First();
+            SelectedEmployee = Employees.FirstOrDefault(x => x.ID == Host.KanbanSettings.StatusSettings.SelectedEmployee) ?? Employees.First();
             EmployeeList.SelectedItem = SelectedEmployee;
             _updatingEmployees = false;
         });
@@ -402,6 +402,8 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
             return;
 
         SelectedEmployee = (EmployeeList.SelectedItem as EmployeeModel)!;
+        Host.KanbanSettings.StatusSettings.SelectedEmployee = SelectedEmployee.ID;
+        Host.SaveSettings();
 
         SelectedTasks.Clear();
         if (IsReady)
@@ -559,6 +561,12 @@ public partial class TasksByStatusControl : UserControl, ITaskControl, INotifyPr
         Refresh();
     }
 
+    private void FilterButton_OnFiltersSelected(DynamicGridSelectedFilterSettings filters)
+    {
+        Host.KanbanSettings.Filters = filters;
+        Host.SaveSettings();
+    }
+
     private static Filter<T> GetSearchFilter<T>(Expression<Func<T, object?>> expression, string searchText) where T : Entity, new()
     {
         Filter<T>? result = null;

+ 2 - 1
prs.desktop/Panels/Tasks/TasksByUserControl.xaml

@@ -128,7 +128,8 @@
                     <DockPanel>
                         <local:TaskPanelFilterButton DockPanel.Dock="Left"
                                                      x:Name="FilterButton"
-                                                     OnFilterRefresh="TaskPanelFilterButton_OnFilterRefresh"/>
+                                                     OnFilterRefresh="TaskPanelFilterButton_OnFilterRefresh"
+                                                     OnFiltersSelected="FilterButton_OnFiltersSelected"/>
                         <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" />

+ 9 - 1
prs.desktop/Panels/Tasks/TasksByUserControl.xaml.cs

@@ -258,6 +258,8 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
         Mode = Host.KanbanSettings.UserSettings.CompactView ? KanbanViewMode.Compact : KanbanViewMode.Full;
 
         PopulateKanbanTypes();
+
+        FilterButton.SetSettings(Host.KanbanSettings.Filters, false);
     }
 
     #endregion
@@ -269,6 +271,12 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
         Refresh();
     }
 
+    private void FilterButton_OnFiltersSelected(DynamicGridSelectedFilterSettings filters)
+    {
+        Host.KanbanSettings.Filters = filters;
+        Host.SaveSettings();
+    }
+
     private void IncludeCompleted_Checked(object sender, RoutedEventArgs e)
     {
         if (!IsReady)
@@ -353,7 +361,7 @@ public partial class TasksByUserControl : UserControl, INotifyPropertyChanged, I
         Model.SectionHeaders.SupressNotification = true;
         Model.SectionHeaders.Clear();
 
-        var emps = Host.KanbanSettings.UserSettings.SelectedEmployees.OrderBy(x => Employees[x].Name).ToArray();
+        var emps = Host.KanbanSettings.UserSettings.SelectedEmployees.Where(x => Employees.ContainsKey(x)).OrderBy(x => Employees[x].Name).ToArray();
 
         foreach (var employeeID in emps)
         {