Quellcode durchsuchen

Added IHasDesktopScript for the purposes of the "Check Script Status" button

Kenric Nugteren vor 1 Woche
Ursprung
Commit
8ee9d310db

+ 1 - 1
prs.classes/EnclosedEntities/Dimensions/DimensionUnit.cs

@@ -8,7 +8,7 @@ using System.Linq;
 namespace Comal.Classes
 {
     
-    public abstract class DimensionUnit : Entity, IRemotable, IPersistent, ISequenceable, IDimensionUnit
+    public abstract class DimensionUnit : Entity, IRemotable, IPersistent, ISequenceable, IDimensionUnit, IHasDesktopScript
     {
         
         [UniqueCodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]

+ 1 - 1
prs.classes/Entities/Bill/Approvals/BillApprovalSet.cs

@@ -6,7 +6,7 @@ using System.Text;
 
 namespace Comal.Classes
 {
-    public class BillApprovalSet : Entity, IRemotable, IPersistent, ILicense<AccountsPayableLicense>
+    public class BillApprovalSet : Entity, IRemotable, IPersistent, ILicense<AccountsPayableLicense>, IHasDesktopScript
     {
         [UniqueCodeEditor]
         [EditorSequence(1)]

+ 1 - 1
prs.classes/Entities/CustomModule/CustomModule.cs

@@ -4,7 +4,7 @@ using InABox.Core;
 namespace Comal.Classes
 {
     [UserTracking(false)]
-    public class CustomModule : Entity, IRemotable, IPersistent, ISchedulable, ILicense<CoreLicense>
+    public class CustomModule : Entity, IRemotable, IPersistent, ISchedulable, ILicense<CoreLicense>, IHasDesktopScript
     {
         [EditorSequence(1)]
         public string Name { get; set; }

+ 1 - 1
prs.classes/Entities/LeaveRequest/Approvals/LeaveRequestApprovalSet.cs

@@ -4,7 +4,7 @@ using InABox.Core;
 
 namespace Comal.Classes
 {
-    public class LeaveRequestApprovalSet : Entity, IRemotable, IPersistent, ILicense<HumanResourcesLicense>
+    public class LeaveRequestApprovalSet : Entity, IRemotable, IPersistent, ILicense<HumanResourcesLicense>, IHasDesktopScript
     {
         [UniqueCodeEditor]
         [EditorSequence(1)]

+ 1 - 1
prs.classes/Settings/AssignmentCostSettings.cs

@@ -34,7 +34,7 @@ namespace Comal.Classes
         FillTimeSheet
     }
 
-    public class AssignmentCostSettings : BaseObject, IGlobalConfigurationSettings
+    public class AssignmentCostSettings : BaseObject, IGlobalConfigurationSettings, IHasDesktopScript
     {
         public AssignmentCostFillAlgorithm Algorithm { get; set; }
 

+ 1 - 1
prs.classes/Settings/StagingPanelSettings.cs

@@ -7,7 +7,7 @@ using System.Text;
 namespace Comal.Classes
 {
     [Caption("Staging Panel Settings")]
-    public class StagingPanellSettings : BaseObject, IGlobalConfigurationSettings
+    public class StagingPanellSettings : BaseObject, IGlobalConfigurationSettings, IHasDesktopScript
     {
         [Caption("PDF Markup Program Pathway", IncludePath = false)]
         [FileNameEditor]

+ 162 - 27
prs.desktop/Forms/Issues/IssuesGrid.cs

@@ -17,6 +17,9 @@ using InABox.Clients;
 using InABox.Scripting;
 using Microsoft.Win32;
 using Microsoft.CodeAnalysis;
+using InABox.Configuration;
+using Document = InABox.Core.Document;
+using System.Configuration;
 
 namespace PRSDesktop.Forms.Issues;
 
@@ -127,40 +130,173 @@ public class IssuesGrid : DynamicGrid<Kanban>, ISpecificGrid
         scriptButton.Margin = new Thickness(20, scriptButton.Margin.Top, scriptButton.Margin.Right, scriptButton.Margin.Bottom);
     }
 
-    private List<Tuple<CustomModule, string>> CheckCustomModules(bool showHidden, bool showWarnings)
+    private interface IScriptReference
     {
-        var results = new List<Tuple<CustomModule, string>>();
-        Progress.ShowModal("Loading Data", progress =>
+        string Name { get; }
+
+        string Script { get; }
+
+        void Update(string script);
+    }
+
+    private class EntityScriptReference(Entity entity, IProperty property) : IScriptReference
+    {
+        public string Name => entity.ToString() ?? entity.GetType().Name;
+
+        public string Script => (property.Getter()(entity) as string) ?? "";
+
+        public void Update(string script)
         {
-            var filter = showHidden
-                ? Filter.All<CustomModule>()
-                : Filter<CustomModule>.Where(x => x.Visible).IsEqualTo(true);
+            property.Setter()(entity, script);
+            Client.Create(entity.GetType()).Save(entity, "Updated by User");
+        }
 
-            var modules = Client.Query(
-                filter,
-                Columns.None<CustomModule>()
-                    .Add(x => x.ID)
-                    .Add(x => x.Section)
-                    .Add(x => x.Name)
-                    .Add(x => x.Script))
-                .ToArray<CustomModule>();
-            foreach(var module in modules)
+        public override string ToString()
+        {
+            return Name;
+        }
+    }
+
+    private class GlobalSettingsScriptReference(IGlobalConfiguration configuration, IGlobalConfigurationSettings settings, IProperty property) : IScriptReference
+    {
+        public string Name => configuration.Section.IsNullOrWhiteSpace() ? settings.GetType().Name : $"{settings.GetType().Name}/{configuration.Section}";
+
+        public string Script => (property.Getter()(settings) as string) ?? "";
+
+        public void Update(string script)
+        {
+            property.Setter()(settings, script);
+            configuration.Save(settings);
+        }
+
+        public override string ToString()
+        {
+            return Name;
+        }
+    }
+
+    private class CustomModuleReference(CustomModule module) : IScriptReference
+    {
+        public string Name => $"{module.Section}/{module.Name}";
+
+        public string Script => module.Script;
+
+        public void Update(string script)
+        {
+            module.Script = script;
+            Client.Save(module, "Updated by User");
+        }
+
+        public override string ToString()
+        {
+            return Name;
+        }
+    }
+
+    private Tuple<Type, IProperty>[]? _desktopScriptedTypes;
+
+    private Tuple<Type, IProperty>[] DesktopScriptedTypes
+    {
+        get
+        {
+            _desktopScriptedTypes ??= CoreUtils.Entities.Where(x => x.HasInterface(typeof(IHasDesktopScript)))
+                .Select(x =>
+                {
+                    var property = DatabaseSchema.LocalProperties(x)
+                        .FirstOrDefault(x => x.Editor is ScriptEditor);
+                    if(property is null)
+                    {
+                        return null;
+                    }
+                    else
+                    {
+                        return new Tuple<Type, IProperty>(x, property);
+                    }
+                })
+                .NotNull()
+                .ToArray();
+            return _desktopScriptedTypes;
+        }
+    }
+
+    private IEnumerable<IScriptReference> GetScripts(bool showHidden)
+    {
+        var filter = showHidden
+            ? Filter.All<CustomModule>()
+            : Filter<CustomModule>.Where(x => x.Visible).IsEqualTo(true);
+
+        var queries = new List<Tuple<IKeyedQueryDef, Func<CoreTable, IEnumerable<IScriptReference>>>>();
+        var extraTasks = new List<Task<IEnumerable<IScriptReference>>>();
+        foreach(var (type, property) in DesktopScriptedTypes)
+        {
+            if (type.IsSubclassOf(typeof(Entity)))
+            {
+                if(type == typeof(CustomModule))
+                {
+                    queries.Add(new(
+                        new KeyedQueryDef<CustomModule>(
+                            filter,
+                            Columns.None<CustomModule>()
+                                .Add(x => x.ID)
+                                .Add(x => x.Section)
+                                .Add(x => x.Name)
+                                .Add(x => x.Script)),
+                        x => x.ToArray<CustomModule>().ToArray(x => new CustomModuleReference(x))));
+                }
+                else
+                {
+                    queries.Add(new(
+                        new KeyedQueryDef(type.Name, type,
+                            Filter.Create(type, property.Name, Operator.IsNotEqualTo, ""),
+                            Columns.None(type)
+                                .Add<Entity>(x => x.ID)
+                                .Add(property.Name)),
+                        x => x.ToObjects(type).Cast<Entity>().Select(x => new EntityScriptReference(x, property))));
+                }
+            }
+            else if (type.HasInterface(typeof(IGlobalConfigurationSettings)))
+            {
+                extraTasks.Add(Task.Run(() =>
+                {
+                    var config = (Activator.CreateInstance(typeof(GlobalConfiguration<>).MakeGenericType(type), "") as IGlobalConfiguration)!;
+                    var result = config.LoadAll();
+                    return result.Select<KeyValuePair<string, IGlobalConfigurationSettings>, IScriptReference>(x =>
+                    {
+                        var thisConfig = (Activator.CreateInstance(typeof(GlobalConfiguration<>).MakeGenericType(type), x.Key) as IGlobalConfiguration)!;
+                        return new GlobalSettingsScriptReference(thisConfig, x.Value, property);
+                    });
+                }));
+            }
+        }
+
+        var results = Client.QueryMultiple(queries.Select(x => x.Item1));
+        return queries.SelectMany(x => x.Item2(results.Get(x.Item1.Key)))
+            .Concat(extraTasks.SelectMany(x => x.Result));
+    }
+
+    private List<Tuple<IScriptReference, string>> CheckCustomModules(bool showHidden, bool showWarnings)
+    {
+        var results = new List<Tuple<IScriptReference, string>>();
+        Progress.ShowModal("Loading Data", progress =>
+        {
+            var scripts = GetScripts(showHidden);
+            foreach(var script in scripts)
             {
                 try
                 {
-                    progress.Report($"{module.Section} -> {module.Name}");
+                    progress.Report(script.Name);
 
-                    var scriptDocument = new ScriptDocument(module.Script);
+                    var scriptDocument = new ScriptDocument("#nullable enable\n" + script.Script);
                     var ok = scriptDocument.Compile();
                     if (!ok || (showWarnings && scriptDocument.Diagnostics.Any(x => x.Severity == DiagnosticSeverity.Error || x.Severity == DiagnosticSeverity.Warning)))
                     {
                         var errors = scriptDocument.Diagnostics.Select(x => x.Contents);
-                        results.Add(new(module, string.Join('\n', errors.Select(x => $"- {x}"))));
+                        results.Add(new(script, string.Join('\n', errors.Select(x => $"- {x}"))));
                     }
                 }
                 catch(Exception e)
                 {
-                    results.Add(new(module, e.Message));
+                    results.Add(new(script, e.Message));
                 }
             }
         });
@@ -195,7 +331,7 @@ public class IssuesGrid : DynamicGrid<Kanban>, ISpecificGrid
             void RebuildList()
             {
                 list.Items.Clear();
-                foreach(var (module, errors) in results)
+                foreach(var (script, errors) in results)
                 {
                     var itemGrid = new Grid
                     {
@@ -213,14 +349,14 @@ public class IssuesGrid : DynamicGrid<Kanban>, ISpecificGrid
                         Height = 30,
                         Padding = new(5),
                         Margin = new(0, 0, 5, 0),
-                        Tag = module
+                        Tag = script
                     };
                     itemBtn.VerticalAlignment = VerticalAlignment.Top;
                     itemBtn.Click += ModuleOpen_Click;
                     itemGrid.AddChild(itemBtn, 0, 0);
                     itemGrid.AddChild(new Label
                     {
-                        Content = $"{module.Section}/{module.Name}:\n{errors}"
+                        Content = $"{script.Name}:\n{errors}"
                     }, 0, 1);
                     list.Items.Add(itemGrid);
                 }
@@ -242,7 +378,7 @@ public class IssuesGrid : DynamicGrid<Kanban>, ISpecificGrid
             };
             exportButton.Click += (o, e) =>
             {
-                var result = string.Join("\n\n", results.Select(x => $"{x.Item1.Section}/{x.Item1.Name}:\n{x.Item2}"));
+                var result = string.Join("\n\n", results.Select(x => $"{x.Item1.Name}:\n{x.Item2}"));
                 var dlg = new SaveFileDialog()
                 {
                     Filter = "Text Files (*.txt)|*.txt"
@@ -291,13 +427,12 @@ public class IssuesGrid : DynamicGrid<Kanban>, ISpecificGrid
     private void ModuleOpen_Click(object sender, RoutedEventArgs e)
     {
         if (sender is not FrameworkElement element
-            || element.Tag is not CustomModule module) return;
+            || element.Tag is not IScriptReference script) return;
 
-        var editor = new ScriptEditorWindow(module.Script, scriptTitle: $"{module.Section}/{module.Name}");
+        var editor = new ScriptEditorWindow(script.Script, scriptTitle: script.Name);
         if (editor.ShowDialog() == true)
         {
-            module.Script = editor.Script;
-            Client.Save(module, "Updated by User");
+            script.Update(editor.Script);
         }
     }
 

+ 1 - 1
prs.desktop/Panels/Manufacturing/ManufacturingPanelProperties.cs

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
 
 namespace PRSDesktop
 {
-    public class ManufacturingPanelProperties : BaseObject, IGlobalConfigurationSettings
+    public class ManufacturingPanelProperties : BaseObject, IGlobalConfigurationSettings, IHasDesktopScript
     {
         [ScriptEditor]
         public string PickingListOptimisationScript { get; set; } = "";

+ 1 - 1
prs.desktop/Utils/CustomImporter.cs

@@ -34,7 +34,7 @@ namespace PRSDesktop
         }
     }
 
-    public class CustomImporterSettings : BaseObject
+    public class CustomImporterSettings : BaseObject, IHasDesktopScript
     {
         [ScriptEditor]
         public string Script { get; set; }