| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551 | 
							- using Comal.Classes;
 
- using FastReport;
 
- using InABox.Clients;
 
- using InABox.Configuration;
 
- using InABox.Core;
 
- using InABox.Core.Reports;
 
- using InABox.DynamicGrid;
 
- using InABox.Scripting;
 
- using InABox.Wpf;
 
- using InABox.Wpf.Reports;
 
- using InABox.WPF;
 
- using PRSDesktop.Configuration;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.ComponentModel;
 
- using System.Drawing;
 
- using System.Linq;
 
- using System.Reflection;
 
- using System.Text;
 
- using System.Threading.Tasks;
 
- using System.Windows;
 
- using System.Windows.Controls;
 
- namespace PRSDesktop;
 
- public interface IPanelHostControl
 
- {
 
-     void ClearActions();
 
-     void CreatePanelAction(PanelAction action);
 
-     void ClearReports();
 
-     void CreateReport(PanelAction action);
 
- }
 
- public class PanelHost : IPanelHost
 
- {
 
-     public IBasePanel? CurrentPanel { get; private set; }
 
-     public string CurrentModuleName { get; private set; } = "";
 
-     private readonly IPanelHostControl HostControl;
 
-     private readonly List<IPanelActionItem> SetupActions = new();
 
-     public PanelHost(IPanelHostControl hostControl)
 
-     {
 
-         HostControl = hostControl;
 
-     }
 
-     #region Module Tracking
 
-     private int TrackedClicks;
 
-     private int TrackedKeys;
 
-     private DateTime TrackedTicks = DateTime.MinValue;
 
-     public void IncrementTrackingModuleClick()
 
-     {
 
-         if (CurrentPanel is not null)
 
-             TrackedClicks++;
 
-     }
 
-     public void IncrementTrackingModuleKey()
 
-     {
 
-         if (CurrentPanel is not null)
 
-             TrackedKeys++;
 
-     }
 
-     #endregion
 
-     #region IPanelHost
 
-     void IPanelHost.CreatePanelAction(PanelAction action)
 
-     {
 
-         HostControl.CreatePanelAction(action);
 
-     }
 
-     void IPanelHost.CreateReport(PanelAction action)
 
-     {
 
-         HostControl.CreateReport(action);
 
-     }
 
-     void IPanelHost.CreateSetupAction(PanelAction action)
 
-     {
 
-         SetupActions.Add(action);
 
-     }
 
-     void IPanelHost.CreateSetupSeparator()
 
-     {
 
-         SetupActions.Add(new PanelActionSeparator());
 
-     }
 
-     #endregion
 
-     #region Panel Properties
 
-     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(PanelHost)
 
-                 .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, IGlobalConfigurationSettings, new()
 
-     {
 
-         panel.Properties = LoadPanelProperties<TPanel, TProperties>();
 
-     }
 
-     private TProperties LoadPanelProperties<TPanel, TProperties>()
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         var config = new GlobalConfiguration<TProperties>();
 
-         return config.Load();
 
-     }
 
-     private void SavePanelProperties<TPanel, TProperties>(TProperties properties)
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         var config = new GlobalConfiguration<TProperties>();
 
-         config.Save(properties);
 
-     }
 
-     private void EditPanelProperties<TPanel, TProperties>()
 
-         where TPanel : IPropertiesPanel<TProperties>
 
-         where TProperties : BaseObject, IGlobalConfigurationSettings, new()
 
-     {
 
-         var properties = LoadPanelProperties<TPanel, TProperties>();
 
-         bool result;
 
-         if (DynamicGridUtils.TryFindDynamicGrid(typeof(DynamicGrid<>), typeof(TProperties), out var gridType))
 
-         {
 
-             var grid = (Activator.CreateInstance(gridType) as DynamicGrid<TProperties>)!;
 
-             result = grid.EditItems(new TProperties[] { properties });
 
-         }
 
-         else
 
-         {
 
-             var grid = new DynamicItemsListGrid<TProperties>();
 
-             result = grid.EditItems(new TProperties[] { properties });
 
-         }
 
-         if (result)
 
-         {
 
-             SavePanelProperties<TPanel, TProperties>(properties);
 
-         }
 
-     }
 
-     private void ConfigurePanel()
 
-     {
 
-         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?>());
 
-     }
 
-     #endregion
 
-     #region Actions
 
-     private void ReloadActions(string sectionName, DataModel model)
 
-     {
 
-         SetupActions.Clear();
 
-         HostControl.ClearActions();
 
-         HostControl.ClearReports();
 
-         CreateModules(sectionName, model);
 
-         if (CurrentPanel != null)
 
-         {
 
-             CurrentPanel.CreateToolbarButtons(this);
 
-         }
 
-         CreateReports(sectionName, model);
 
-     }
 
-     #endregion
 
-     #region Custom Modules
 
-     private void CreateModules(string section, DataModel model)
 
-     {
 
-         if (ClientFactory.IsSupported<CustomModule>())
 
-         {
 
-             foreach (var (module, image) in CustomModuleUtils.LoadCustomModuleThumbnails(section, model))
 
-             {
 
-                 HostControl.CreatePanelAction(new PanelAction
 
-                 {
 
-                     Caption = module.Name ?? "",
 
-                     Image = image,
 
-                     OnExecute = (action) =>
 
-                     {
 
-                         ClickModule(action, module);
 
-                     }
 
-                 });
 
-             }
 
-         }
 
-     }
 
-     private void ClickModule(PanelAction action, CustomModule code)
 
-     {
 
-         if (CurrentPanel != null)
 
-         {
 
-             if (!string.IsNullOrWhiteSpace(code.Script))
 
-                 try
 
-                 {
 
-                     Selection selection;
 
-                     if (code.SelectedRecords && code.AllRecords)
 
-                         selection = RecordSelectionDialog.Execute();
 
-                     else if (code.SelectedRecords)
 
-                         selection = Selection.Selected;
 
-                     else if (code.AllRecords)
 
-                         selection = Selection.All;
 
-                     else
 
-                         selection = Selection.None;
 
-                     var result = ScriptDocument.RunCustomModule(CurrentPanel.DataModel(selection), CurrentPanel.Selected(), code.Script);
 
-                     if (result)
 
-                         CurrentPanel.Refresh();
 
-                 }
 
-                 catch (CompileException c)
 
-                 {
 
-                     MessageWindow.ShowError(c.Message, c, shouldLog: false);
 
-                 }
 
-                 catch (Exception err)
 
-                 {
 
-                     MessageWindow.ShowError($"Unable to load {action.Caption}", err);
 
-                 }
 
-             else
 
-                 MessageWindow.ShowMessage("Unable to load " + action.Caption, "Error", image: MessageWindow.WarningImage);
 
-         }
 
-     }
 
-     private void ManageModules(PanelAction action)
 
-     {
 
-         if (CurrentPanel != null)
 
-         {
 
-             var section = CurrentPanel.SectionName;
 
-             var dataModel = CurrentPanel.DataModel(Selection.Selected);
 
-             var manager = new CustomModuleManager()
 
-             {
 
-                 Section = section,
 
-                 DataModel = dataModel
 
-             };
 
-             manager.ShowDialog();
 
-             ReloadActions(section, dataModel);
 
-         }
 
-     }
 
-     #endregion
 
-     #region Reports
 
-     private IEnumerable<ReportExportDefinition> AddTemplateDefinitions()
 
-     {
 
-         if (CurrentPanel is null)
 
-             return new List<ReportExportDefinition>() { new ReportExportDefinition("Email Report", PRSDesktop.Resources.email, ReportExportType.PDF,
 
-                             PRSEmailUtils.DoEmailReport)};
 
-         else
 
-             return PRSEmailUtils.CreateTemplateDefinitions(CurrentPanel.DataModel(Selection.None));
 
-     }
 
-     public static PanelAction CreateReportAction(ReportTemplate template, Func<Selection, DataModel> getDataModel)
 
-     {
 
-         var action = new PanelAction
 
-         {
 
-             Caption = template.Name,
 
-             Image = PRSDesktop.Resources.printer,
 
-             OnExecute = (action) =>
 
-             {
 
-                 PrintReport(template.ID, getDataModel);
 
-             }
 
-         };
 
-         if (Security.IsAllowed<CanDesignReports>())
 
-         {
 
-             var menu = new ContextMenu();
 
-             menu.AddItem("Design Report", PRSDesktop.Resources.pencil, () => DesignReport(template.ID, getDataModel));
 
-             action.Menu = menu;
 
-         }
 
-         return action;
 
-     }
 
-     private void CreateReports(string section, DataModel model)
 
-     {
 
-         if (CurrentPanel is null) return;
 
-         var client = new Client<ReportTemplate>();
 
-         var templates = ReportUtils.LoadReports(section, model, new Columns<ReportTemplate>(x => x.ID, x => x.Name));
 
-         foreach (var template in templates)
 
-         {
 
-             HostControl.CreateReport(CreateReportAction(template, CurrentPanel.DataModel));
 
-         }
 
-     }
 
-     private static void DesignReport(Guid templateID, Func<Selection, DataModel> getDataModel)
 
-     {
 
-         var template = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.ID).IsEqualTo(templateID)).FirstOrDefault();
 
-         if (template is null)
 
-         {
 
-             Logger.Send(LogType.Error, "", $"No Report Template with ID '{templateID}'");
 
-             MessageWindow.ShowMessage("Report does not exist!", "Error", image: MessageWindow.WarningImage);
 
-             return;
 
-         }
 
-         ReportUtils.DesignReport(template, getDataModel(Selection.None));
 
-     }
 
-     private static void PrintReport(Guid id, Func<Selection, DataModel> getDataModel)
 
-     {
 
-         var template = new Client<ReportTemplate>().Load(new Filter<ReportTemplate>(x => x.ID).IsEqualTo(id)).FirstOrDefault();
 
-         if (template == null)
 
-         {
 
-             Logger.Send(LogType.Error, "", $"No Report Template with ID '{id}'");
 
-             MessageWindow.ShowMessage("Report does not exist!", "Error", image: MessageWindow.WarningImage);
 
-             return;
 
-         }
 
-         var selection = Selection.None;
 
-         if (template.SelectedRecords && template.AllRecords)
 
-             selection = RecordSelectionDialog.Execute();
 
-         else if (template.SelectedRecords)
 
-             selection = Selection.Selected;
 
-         else if (template.AllRecords)
 
-             selection = Selection.All;
 
-         else
 
-             MessageWindow.ShowMessage(
 
-                 "Report must have either [Selected Records] or [All Records] checked to display!",
 
-                 "Error",
 
-                 image: MessageWindow.WarningImage);
 
-         if (selection != Selection.None)
 
-             ReportUtils.PreviewReport(template, getDataModel(selection), false, Security.IsAllowed<CanDesignReports>());
 
-     }
 
-     private void ManageReports(PanelAction action)
 
-     {
 
-         if (CurrentPanel is null)
 
-             return;
 
-         var section = CurrentPanel.SectionName;
 
-         var model = CurrentPanel.DataModel(Selection.None);
 
-         if (model == null)
 
-         {
 
-             MessageWindow.ShowMessage("No DataModel for " + CurrentPanel.SectionName, "No DataModel");
 
-             return;
 
-         }
 
-         var form = new ReportManager { DataModel = model, Section = section, Populate = true };
 
-         form.ShowDialog();
 
-         ReloadActions(section, model);
 
-     }
 
-     private void ManageEmailTemplates(PanelAction action)
 
-     {
 
-         if (CurrentPanel is null)
 
-             return;
 
-         var section = CurrentPanel.SectionName;
 
-         var model = CurrentPanel.DataModel(Selection.None);
 
-         if (model == null)
 
-         {
 
-             MessageWindow.ShowMessage("No DataModel for " + section, "No DataModel");
 
-             return;
 
-         }
 
-         var window = new EmailTemplateManagerWindow(model);
 
-         window.ShowDialog();
 
-     }
 
-     #endregion
 
-     #region Public Interface
 
-     public void InitialiseSetupMenu(ContextMenu menu)
 
-     {
 
-         var items = new List<IPanelActionItem>();
 
-         items.AddRange(SetupActions);
 
-         items.Add(new PanelActionSeparator());
 
-         if (Security.IsAllowed<CanCustomiseModules>())
 
-         {
 
-             items.Add(new PanelAction("Custom Modules", PRSDesktop.Resources.script, ManageModules));
 
-         }
 
-         if (Security.IsAllowed<CanDesignReports>())
 
-         {
 
-             items.Add(new PanelAction("Reports", PRSDesktop.Resources.printer, ManageReports));
 
-         }
 
-         if (Security.IsAllowed<CanDesignReports>())
 
-         {
 
-             items.Add(new PanelAction("Email Templates", PRSDesktop.Resources.email, ManageEmailTemplates));
 
-         }
 
-         for (var i = 0; i < items.Count; ++i)
 
-         {
 
-             var item = items[i];
 
-             if (item is PanelAction setupAction)
 
-             {
 
-                 menu.AddItem(setupAction.Caption, setupAction.Image, setupAction, setupAction.OnExecute);
 
-             }
 
-             else if (item is PanelActionSeparator && i > 0 && i < items.Count - 1)
 
-             {
 
-                 var last = items[i - 1];
 
-                 if (last is not PanelActionSeparator)
 
-                     menu.AddSeparator();
 
-             }
 
-         }
 
-         if (CurrentPanel?.GetType().HasInterface(typeof(IPropertiesPanel<>)) == true && Security.IsAllowed<CanConfigurePanels>())
 
-         {
 
-             var securityInterface = CurrentPanel?.GetType().GetInterfaceDefinition(typeof(IPropertiesPanel<,>));
 
-             var canConfigure = false;
 
-             if (securityInterface is not null)
 
-             {
 
-                 var token = securityInterface.GenericTypeArguments[1];
 
-                 canConfigure = Security.IsAllowed(token);
 
-             }
 
-             else
 
-             {
 
-                 canConfigure = Security.IsAllowed<CanConfigurePanels>();
 
-             }
 
-             if (canConfigure)
 
-             {
 
-                 menu.AddItem("Configure Panel", PRSDesktop.Resources.edit, ConfigurePanel);
 
-             }
 
-         }
 
-         if (menu.Items.Count == 0)
 
-         {
 
-             menu.AddItem("No Items", null, null, false);
 
-         }
 
-     }
 
-     public IBasePanel LoadPanel(Type T, string moduleName)
 
-     {
 
-         return (LoadPanelMethod.MakeGenericMethod(T).Invoke(this, new object[] { moduleName })
 
-             as IBasePanel)!;
 
-     }
 
-     private static readonly MethodInfo LoadPanelMethod = typeof(PanelHost)
 
-         .GetMethods().First(x => x.Name == nameof(LoadPanel) && x.IsGenericMethod);
 
-     public T LoadPanel<T>(string moduleName) where T : class, IBasePanel, new()
 
-     {
 
-         var panel = new T();
 
-         CurrentPanel = panel;
 
-         ReportUtils.ExportDefinitions.Clear();
 
-         ReportUtils.ExportDefinitions.AddRange(AddTemplateDefinitions());
 
-         InitializePanelProperties(panel);
 
-         CurrentModuleName = moduleName;
 
-         TrackedTicks = DateTime.Now;
 
-         CurrentPanel.IsReady = false;
 
-         CurrentPanel.Setup();
 
-         CurrentPanel.IsReady = true;
 
-         CurrentPanel.OnUpdateDataModel += ReloadActions;
 
-         var model = CurrentPanel.DataModel(Selection.None);
 
-         var section = CurrentPanel.SectionName;
 
-         ReloadActions(section, model);
 
-         return panel;
 
-     }
 
-     public void Refresh()
 
-     {
 
-         CurrentPanel?.Refresh();
 
-     }
 
-     private void Heartbeat(TimeSpan time, bool closing)
 
-     {
 
-         if (!closing && time.TotalMinutes < 5)
 
-             return;
 
-         TrackedTicks = DateTime.Now;
 
-         if (CurrentPanel is not null)
 
-         {
 
-             //Logger.Send(LogType.Information, "", string.Format("Heartbeat: {0}", CurrentPanel_Label));
 
-             if (ClientFactory.IsSupported<ModuleTracking>())
 
-             {
 
-                 var keys = TrackedKeys;
 
-                 TrackedKeys = 0;
 
-                 var clicks = TrackedClicks;
 
-                 TrackedClicks = 0;
 
-                 var tracking = new ModuleTracking
 
-                 {
 
-                     Date = DateTime.Today,
 
-                     Module = CurrentModuleName,
 
-                     Clicks = clicks,
 
-                     Keys = keys,
 
-                     ActiveTime = clicks + keys > 0 ? time : new TimeSpan(),
 
-                     IdleTime = clicks + keys == 0 ? time : new TimeSpan()
 
-                 };
 
-                 tracking.User.ID = ClientFactory.UserGuid;
 
-                 new Client<ModuleTracking>().Save(tracking, "", (mt, ex) => { });
 
-             }
 
-             CurrentPanel.Heartbeat(time);
 
-         }
 
-     }
 
-     public void Heartbeat()
 
-     {
 
-         Heartbeat(DateTime.Now - TrackedTicks, false);
 
-     }
 
-     public void UnloadPanel(CancelEventArgs? cancel)
 
-     {
 
-         if (CurrentPanel != null)
 
-         {
 
-             Heartbeat(DateTime.Now - TrackedTicks, true);
 
-             try
 
-             {
 
-                 CurrentPanel.Shutdown(cancel);
 
-                 if (cancel?.Cancel == true)
 
-                 {
 
-                     return;
 
-                 }
 
-             }
 
-             catch (Exception e)
 
-             {
 
-                 Logger.Send(LogType.Error, ClientFactory.UserID, string.Format("Error in UnloadPanel(): {0}\n{1}", e.Message, e.StackTrace));
 
-             }
 
-             TrackedTicks = DateTime.MinValue;
 
-             CurrentModuleName = "";
 
-             TrackedClicks = 0;
 
-             TrackedKeys = 0;
 
-         }
 
-     }
 
-     #endregion
 
- }
 
 
  |