Преглед на файлове

New panel configuration settings

Kenric Nugteren преди 2 години
родител
ревизия
a09f7c3fd7

+ 5 - 0
prs.classes/SecurityDescriptors/Common_Descriptors.cs

@@ -7,6 +7,11 @@ namespace Comal.Classes
     {
     }
 
+    [Caption("Can Configure Panels")]
+    public class CanConfigurePanels : DisabledSecurityDescriptor<CoreLicense>
+    {
+    }
+
     [Caption("View In/Out Module")]
     public class CanViewInOutBoard : EnabledSecurityDescriptor<HumanResourcesLicense, TimeSheet, LeaveRequest>
     {

+ 0 - 1
prs.desktop/Dashboards/QADashboard.xaml.cs

@@ -373,7 +373,6 @@ namespace PRSDesktop
                 if (link != null)
                 {
                     return instance;
-                    break;
                 }
             }
 

+ 64 - 0
prs.desktop/MainWindow.xaml.cs

@@ -1172,6 +1172,8 @@ namespace PRSDesktop
                 var panel = new T();
                 CurrentPanel = panel;
 
+                InitializePanelProperties(panel);
+
                 CurrentPanel.IsReady = false;
                 CurrentPanel.Setup();
                 CurrentPanel.IsReady = true;
@@ -2500,6 +2502,11 @@ namespace PRSDesktop
                         menu.AddSeparator();
                 }
             }
+            if(CurrentPanel?.GetType().HasInterface(typeof(IPropertiesPanel<>)) == true && Security.IsAllowed<CanConfigurePanels>())
+            {
+                menu.AddItem("Configure Panel", PRSDesktop.Resources.edit, ConfigurePanel_Click);
+            }
+
             if (menu.Items.Count == 0)
             {
                 menu.AddItem("No Items", null, null, false);
@@ -2507,6 +2514,63 @@ namespace PRSDesktop
             menu.IsOpen = true;
         }
 
+        private void InitializePanelProperties(IBasePanel panel)
+        {
+            var propertiesInterface = panel.GetType().GetInterfaceDefinition(typeof(IPropertiesPanel<>));
+            if (propertiesInterface is not null)
+            {
+                var propertiesType = propertiesInterface.GenericTypeArguments[0];
+                var method = typeof(MainWindow)
+                    .GetMethod(nameof(InitializePanelPropertiesGeneric), BindingFlags.NonPublic | BindingFlags.Instance)
+                    ?.MakeGenericMethod(panel.GetType(), propertiesType)
+                    .Invoke(this, new object?[] { panel });
+            }
+        }
+        private void InitializePanelPropertiesGeneric<TPanel, TProperties>(TPanel panel)
+            where TPanel : IPropertiesPanel<TProperties>
+            where TProperties : BaseObject, GlobalConfigurationSettings, new()
+        {
+            panel.Properties = LoadPanelProperties<TPanel, TProperties>();
+        }
+        private TProperties LoadPanelProperties<TPanel, TProperties>()
+            where TPanel : IPropertiesPanel<TProperties>
+            where TProperties : BaseObject, GlobalConfigurationSettings, new()
+        {
+            var config = new GlobalConfiguration<TProperties>();
+            return config.Load();
+        }
+        private void SavePanelProperties<TPanel, TProperties>(TProperties properties)
+            where TPanel : IPropertiesPanel<TProperties>
+            where TProperties : BaseObject, GlobalConfigurationSettings, new()
+        {
+            var config = new GlobalConfiguration<TProperties>();
+            config.Save(properties);
+        }
+        private void EditPanelProperties<TPanel, TProperties>()
+            where TPanel : IPropertiesPanel<TProperties>
+            where TProperties : BaseObject, GlobalConfigurationSettings, new()
+        {
+            var properties = LoadPanelProperties<TPanel, TProperties>();
+            var editor = new DynamicEditorForm(typeof(TProperties));
+            editor.Items = new BaseObject[] { properties };
+            if(editor.ShowDialog() == true)
+            {
+                SavePanelProperties<TPanel, TProperties>(properties);
+            }
+        }
+
+        private void ConfigurePanel_Click()
+        {
+            if (CurrentPanel is null) return;
+
+            var propertiesInterface = CurrentPanel.GetType().GetInterfaceDefinition(typeof(IPropertiesPanel<>))!;
+            var propertiesType = propertiesInterface.GenericTypeArguments[0];
+            var method = typeof(MainWindow)
+                .GetMethod(nameof(EditPanelProperties), BindingFlags.NonPublic | BindingFlags.Instance)
+                ?.MakeGenericMethod(CurrentPanel.GetType(), propertiesType)
+                .Invoke(this, Array.Empty<object?>());
+        }
+
         private void StartForm<TEntityForm, TEntity, TEntityLink>(DigitalForm form)
             where TEntityForm : EntityForm<TEntity, TEntityLink>, new()
             where TEntity : Entity, new()

+ 7 - 0
prs.desktop/Panels/IPanel.cs

@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Drawing;
+using InABox.Configuration;
 using InABox.Core;
 
 namespace PRSDesktop
@@ -44,6 +45,12 @@ namespace PRSDesktop
     {
     }
 
+    public interface IPropertiesPanel<TProperties>
+        where TProperties : BaseObject, GlobalConfigurationSettings, new()
+    {
+        public TProperties Properties { get; set; }
+    }
+
     public interface IPanelHost
     {
         void CreatePanelAction(PanelAction action);

+ 2 - 2
prs.desktop/Panels/Jobs/JobSummaryGrid.cs

@@ -114,8 +114,8 @@ namespace PRSDesktop
             return result;
         }
 
-        protected override void Reload(Filters<JobMaterial> criteria, Columns<JobMaterial> columns, ref SortOrder<JobMaterial> sort,
-            Action<CoreTable, Exception> action)
+        protected override void Reload(Filters<JobMaterial> criteria, Columns<JobMaterial> columns, ref SortOrder<JobMaterial>? sort,
+            Action<CoreTable?, Exception?> action)
         {
             if (JobID == Guid.Empty)
                 criteria.Add(new Filter<JobMaterial>().None());

+ 35 - 9
prs.desktop/Panels/Tasks/TaskPanel.xaml.cs

@@ -14,18 +14,22 @@ using InABox.DynamicGrid;
 using InABox.WPF;
 using Syncfusion.Pdf.Graphics;
 using Syncfusion.Pdf;
-using gnu.java.awt.color;
 using System.Windows.Data;
 using System.Windows.Media;
 using System.Drawing;
-using static com.sun.tools.javac.code.Symbol;
 
 namespace PRSDesktop
 {
+    public class TaskPanelProperties : BaseObject, GlobalConfigurationSettings
+    {
+        [CheckBoxEditor(ToolTip = "Require that all tasks are given a task type.")]
+        public bool RequireTaskTypes { get; set; } = false;
+    }
+
     /// <summary>
     ///     Interaction logic for TaskPanel.xaml
     /// </summary>
-    public partial class TaskPanel : UserControl, IPanel<Kanban>, ITaskHost, IJobControl
+    public partial class TaskPanel : UserControl, IPanel<Kanban>, ITaskHost, IJobControl, IPropertiesPanel<TaskPanelProperties>
     {
         private bool _bTabChanging;
         public Guid MyID { get; set; } = CoreUtils.FullGuid;
@@ -826,7 +830,9 @@ namespace PRSDesktop
             GetCurrentPanel()?.Refresh(false);
         }
 
-        public string? SectionName => GetCurrentPanel().SectionName;
+        public string SectionName => GetCurrentPanel().SectionName;
+
+        public TaskPanelProperties Properties { get; set; }
 
         public DataModel DataModel(Selection selection)
         {
@@ -838,26 +844,33 @@ namespace PRSDesktop
 
         #region CRUD Functionality
 
-        private TEntity? DoCreate<TEntity>(Action<TEntity> customise) where TEntity : Entity, IRemotable, IPersistent, new()
+        private TEntity? DoCreate<TEntity>(Action<TEntity> customise)
+            where TEntity : Entity, IRemotable, IPersistent, new()
         {
             var result = new TEntity();
             customise?.Invoke(result);
-            if (DoEdit(new[] { result }))
+            if (DoEdit(new[] { result }, null))
                 return result;
             return null;
         }
 
-        private static readonly Dictionary<Type, IDynamicGrid> _grids = new();
+        private readonly Dictionary<Type, IDynamicGrid> _grids = new();
 
         private readonly List<Tuple<Guid, Entity>> _entitycache = new();
 
-        private static DynamicDataGrid<TEntity> GetGrid<TEntity>() where TEntity : Entity, IRemotable, IPersistent, new()
+        private DynamicDataGrid<TEntity> GetGrid<TEntity>() where TEntity : Entity, IRemotable, IPersistent, new()
         {
             if(!_grids.TryGetValue(typeof(TEntity), out var grid))
             {
                 grid = (DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(TEntity)) as DynamicDataGrid<TEntity>)!;
                 _grids[typeof(TEntity)] = grid;
+
+                if (typeof(TEntity) == typeof(Kanban))
+                {
+                    CustomiseKanbanGrid((grid as DynamicDataGrid<Kanban>)!);
+                }
             }
+
             return (grid as DynamicDataGrid<TEntity>)!;
         }
 
@@ -915,7 +928,7 @@ namespace PRSDesktop
                 _entitycache.Add(new Tuple<Guid, Entity>(kanbanid, entity));
         }
 
-        private static bool DoEdit<TEntity>(IEnumerable<TEntity> entities, Action<TEntity>? action = null)
+        private bool DoEdit<TEntity>(IEnumerable<TEntity> entities, Action<TEntity>? action = null)
             where TEntity : Entity, IRemotable, IPersistent, new()
         {
             if (entities == null || !entities.Any())
@@ -991,6 +1004,19 @@ namespace PRSDesktop
             return DoLoad(models, columns);
         }
 
+        public void OnValidateKanban(object sender, Kanban[] items, List<string> errors)
+        {
+            if (Properties.RequireTaskTypes && items.Any(x => x.Type.ID == Guid.Empty))
+            {
+                errors.Add("[Task Type] may not be blank!");
+            }
+        }
+
+        public void CustomiseKanbanGrid(DynamicDataGrid<Kanban> grid)
+        {
+            grid.OnValidate += OnValidateKanban;
+        }
+
         public bool EditKanbans(IEnumerable<TaskModel> models, Action<Kanban>? customise = null)
         {
             var entities = LoadKanbans(models, GetGrid<Kanban>().LoadEditorColumns());

+ 1 - 2
prs.server/Forms/ServerGrid.cs

@@ -1038,8 +1038,7 @@ namespace PRSServer
                 x => selectedrow.Get<Server, string>(x => x.Key),
                 () =>
                 {
-                    //new LicenseRenewalForm().ShowDialog();
-                    MessageBox.Show("Not yet implemented.");
+                    new LicenseRenewalForm().ShowDialog();
                 }
             );
             return false;