UtilityDashboard.xaml.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Linq;
  5. using System.Reflection;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Media;
  9. using Comal.Classes;
  10. using InABox.Configuration;
  11. using InABox.Core;
  12. using InABox.DynamicGrid;
  13. using InABox.WPF;
  14. using InABox.Wpf;
  15. using InABox.WPF.Themes;
  16. using Microsoft.Xaml.Behaviors.Core;
  17. using Syncfusion.Windows.Tools.Controls;
  18. using PRSDesktop.Dashboards;
  19. using InABox.Wpf.Dashboard.Editor;
  20. using InABox.Wpf.Dashboard;
  21. namespace PRSDesktop
  22. {
  23. public class DashboardFavourite : BaseObject
  24. {
  25. [TextBoxEditor]
  26. [EditorSequence(1)]
  27. public string Name { get; set; }
  28. [CheckBoxEditor]
  29. [EditorSequence(2)]
  30. public bool IsGlobal { get; set; }
  31. [NullEditor]
  32. public string Layout { get; set; }
  33. }
  34. public class CustomDashboard : BaseObject
  35. {
  36. public string Name { get; set; }
  37. public string Group { get; set; }
  38. [NullEditor]
  39. public string Layout { get; set; }
  40. }
  41. public class GlobalUtilityDashboardSettings : IGlobalConfigurationSettings
  42. {
  43. public List<DashboardFavourite> Favourites { get; set; }
  44. public List<CustomDashboard> CustomDashboards { get; set; }
  45. public GlobalUtilityDashboardSettings()
  46. {
  47. Favourites = new();
  48. CustomDashboards = new();
  49. }
  50. }
  51. public class UtilityDashboardSettings : IUserConfigurationSettings
  52. {
  53. public UtilityDashboardSettings()
  54. {
  55. Dashboards = new Dictionary<string, string>();
  56. Favourites = new();
  57. }
  58. public Dictionary<string, string> Dashboards { get; set; }
  59. public List<DashboardFavourite> Favourites { get; set; }
  60. public int Selected { get; set; }
  61. public bool AutoHide { get; set; }
  62. }
  63. /// <summary>
  64. /// Interaction logic for UtilityDashboard.xaml
  65. /// </summary>
  66. public partial class UtilityDashboard : UserControl, IBasePanel
  67. {
  68. private readonly Dictionary<string, DynamicFormDesignGrid> _dashboards = new();
  69. private readonly Dictionary<DynamicFormDesignGrid, List<ICorePanel>> _panels = new();
  70. private class WidgetDashboardElement
  71. {
  72. public Type DashboardElement { get; set; }
  73. public Type Widget { get; set; }
  74. public Type Group { get; set; }
  75. public Type Properties { get; set; }
  76. public string GroupCaption { get; set; }
  77. public string WidgetCaption { get; set; }
  78. public Type[] SecurityTokens { get; set; }
  79. public WidgetDashboardElement(Type dashboardElement, Type widget, Type group, Type properties, Type[] securityTokens)
  80. {
  81. DashboardElement = dashboardElement;
  82. Widget = widget;
  83. Group = group;
  84. Properties = properties;
  85. SecurityTokens = securityTokens;
  86. GroupCaption = UtilityDashboard.GetCaption(group);
  87. WidgetCaption = UtilityDashboard.GetCaption(widget);
  88. }
  89. }
  90. private static List<WidgetDashboardElement>? _dashboardElements;
  91. private string? CurrentDashboardName => DashboardsTab.SelectedTab?.Header?.ToString();
  92. private DynamicFormDesignGrid? CurrentDashboard => CurrentDashboardName != null ? _dashboards.GetValueOrDefault(CurrentDashboardName) : null;
  93. private UtilityDashboardSettings _settings = new();
  94. public UtilityDashboard()
  95. {
  96. InitializeComponent();
  97. }
  98. public void CreateToolbarButtons(IPanelHost host)
  99. {
  100. host.CreateSetupAction("Manage Custom Dashboards", null, ManageCustomDashboards_Click);
  101. }
  102. private void ManageCustomDashboards_Click(PanelAction action)
  103. {
  104. var config = new GlobalConfiguration<GlobalUtilityDashboardSettings>();
  105. var settings = config.Load();
  106. var grid = new CustomDashboardGrid();
  107. grid.Items = settings.CustomDashboards;
  108. }
  109. private void SaveSettings()
  110. {
  111. new UserConfiguration<UtilityDashboardSettings>().Save(_settings);
  112. }
  113. #region Panel Functions & Properties
  114. public event DataModelUpdateEvent? OnUpdateDataModel;
  115. public bool IsReady { get; set; }
  116. public string SectionName => "Utility Dashboard";
  117. public DataModel DataModel(Selection selection)
  118. {
  119. return new EmptyDataModel();
  120. }
  121. public void Setup()
  122. {
  123. _settings = new UserConfiguration<UtilityDashboardSettings>().Load();
  124. if (_settings.Dashboards.Count == 0) _settings.Dashboards["New Dashboard"] = CreateForm("").SaveLayout();
  125. foreach (var key in _settings.Dashboards.Keys)
  126. CreateTab(key);
  127. if (_settings.Selected >= -1 && _settings.Selected < DashboardsTab.Items.Count)
  128. DashboardsTab.SelectedIndex = _settings.Selected;
  129. //DashboardsTab.FullScreenMode = _settings.AutoHide ? FullScreenMode.ControlMode : FullScreenMode.None;
  130. }
  131. public Dictionary<string, object[]> Selected()
  132. {
  133. return new Dictionary<string, object[]>();
  134. }
  135. public void Heartbeat(TimeSpan time)
  136. {
  137. }
  138. public void Refresh()
  139. {
  140. if(CurrentDashboardName is string name)
  141. {
  142. RefreshDashboard(name);
  143. }
  144. }
  145. public void Shutdown(CancelEventArgs? cancel)
  146. {
  147. foreach (var (name, grid) in _dashboards)
  148. {
  149. ShutdownDashboard(name, grid);
  150. }
  151. _panels.Clear();
  152. }
  153. #endregion
  154. #region Favourites
  155. private IEnumerable<DashboardFavourite> GetFavourites()
  156. {
  157. foreach(var favourite in _settings.Favourites)
  158. {
  159. yield return favourite;
  160. }
  161. var global = new GlobalConfiguration<GlobalUtilityDashboardSettings>().Load(false).Favourites;
  162. foreach (var favourite in global)
  163. {
  164. yield return favourite;
  165. }
  166. }
  167. private void ManageFavourites_Click()
  168. {
  169. var favourites = GetFavourites().ToList();
  170. var grid = new DynamicItemsListGrid<DashboardFavourite>() { Items = favourites };
  171. grid.Reconfigure(options =>
  172. {
  173. options.DeleteRows = true;
  174. options.EditRows = true;
  175. options.MultiSelect = true;
  176. });
  177. grid.OnCustomiseEditor += FavouritesGrid_OnCustomiseEditor;
  178. DynamicGridUtils.CreateGridWindow("Manage Favourites", grid).ShowDialog();
  179. _settings.Favourites = favourites.Where(x => !x.IsGlobal).ToList();
  180. SaveSettings();
  181. if (Security.IsAllowed<CanSetGlobalDashboardFavourites>())
  182. {
  183. var config = new GlobalConfiguration<GlobalUtilityDashboardSettings>();
  184. var global = config.Load();
  185. global.Favourites = favourites.Where(x => x.IsGlobal).ToList();
  186. config.Save(global);
  187. }
  188. }
  189. private void FavouritesGrid_OnCustomiseEditor(IDynamicEditorForm sender, DashboardFavourite[]? items, DynamicGridColumn column, BaseEditor editor)
  190. {
  191. if(column.ColumnName == "IsGlobal")
  192. {
  193. editor.Editable = Security.IsAllowed<CanSetGlobalDashboardFavourites>() ? Editable.Enabled : Editable.Disabled;
  194. }
  195. }
  196. private void SaveAsFavourite_Click(string dashboardName)
  197. {
  198. _settings.Favourites.Add(new DashboardFavourite
  199. {
  200. Name = dashboardName,
  201. Layout = _dashboards.GetValueOrDefault(dashboardName)?.Form.SaveLayout() ?? _settings.Dashboards[dashboardName]
  202. });
  203. SaveSettings();
  204. }
  205. private void LoadFavourite_Click(DashboardFavourite favourite)
  206. {
  207. var name = CreateNewTabName(favourite.Name);
  208. _settings.Dashboards[name] = favourite.Layout;
  209. SaveSettings();
  210. var tab = CreateTab(name);
  211. DashboardsTab.SelectedItem = tab;
  212. }
  213. #endregion
  214. #region Tabs
  215. private void Tab_OnContextMenuOpening(object sender, DynamicTabItemContextMenuEventArgs args)
  216. {
  217. var name = (DashboardsTab.SelectedItem as DynamicTabItem)?.Header?.ToString();
  218. if (string.IsNullOrEmpty(name))
  219. return;
  220. DynamicFormDesignGrid grid = _dashboards[name];
  221. var menu = args.Menu;
  222. menu.AddSeparatorIfNeeded();
  223. var isDesigning = grid.Mode != FormMode.Preview;
  224. menu.Items.Add(new MenuItem()
  225. {
  226. Header = isDesigning ? "Close Design Mode" : "Design Mode",
  227. Command = new ActionCommand(() =>
  228. {
  229. if (grid.Mode == FormMode.Designing)
  230. {
  231. grid.Mode = FormMode.Preview;
  232. SaveCurrentDashboard();
  233. DashboardsTab.ChangedCommand.Execute(null);
  234. }
  235. else
  236. {
  237. ShutdownDashboard();
  238. grid.Mode = FormMode.Designing;
  239. }
  240. }),
  241. Icon = new Image() { Source = (isDesigning ? InABox.Wpf.Resources.delete : PRSDesktop.Resources.pencil).AsBitmapImage(24, 24) }
  242. });
  243. var index = 0;
  244. var favourites = GetFavourites().ToList();
  245. if (favourites.Any())
  246. {
  247. foreach (var favourite in favourites)
  248. {
  249. menu.AddItem(favourite.Name, null, favourite, LoadFavourite_Click, index: index++);
  250. }
  251. menu.AddSeparatorIfNeeded(index: index++);
  252. menu.AddItem("Manage Favourites", null, ManageFavourites_Click, index: index++);
  253. }
  254. menu.AddItem("Save as Favourite", null, name, SaveAsFavourite_Click, index: index++);
  255. menu.AddSeparator(index: index++);
  256. }
  257. private void Tab_OnCloseTab(object sender, DynamicTabControlEventArgs args)
  258. {
  259. var name = args.TabItem.Header?.ToString();
  260. if (name is null)
  261. return;
  262. _dashboards.Remove(name);
  263. _settings.Dashboards.Remove(name);
  264. if (!_settings.Dashboards.Any())
  265. {
  266. var tab = new DynamicTabItem();
  267. InitializeNewDashboardTab(tab);
  268. DashboardsTab.Items.Add(tab);
  269. }
  270. else
  271. {
  272. DashboardsTab.ChangedCommand.Execute(null);
  273. }
  274. }
  275. private void Tab_OnTabRenamed(object sender, DynamicTabItemRenamedEventArgs args)
  276. {
  277. var oldSettings = _settings.Dashboards[args.OldName];
  278. _settings.Dashboards.Remove(args.OldName);
  279. args.NewName = CreateNewTabName(args.NewName);
  280. if (_dashboards.TryGetValue(args.OldName, out var dashboard))
  281. {
  282. _dashboards.Remove(args.OldName);
  283. _dashboards[args.NewName] = dashboard;
  284. _settings.Dashboards[args.NewName] = dashboard.Form.SaveLayout();
  285. }
  286. else
  287. {
  288. _settings.Dashboards[args.NewName] = oldSettings;
  289. }
  290. }
  291. /// <summary>
  292. /// Setup events on a new tab.
  293. /// </summary>
  294. /// <param name="tab"></param>
  295. private void InitializeTab(DynamicTabItem tab)
  296. {
  297. tab.CanClose = true;
  298. tab.OnCloseTab += Tab_OnCloseTab;
  299. tab.CanRename = true;
  300. tab.OnTabRenamed += Tab_OnTabRenamed;
  301. tab.OnContextMenuOpening += Tab_OnContextMenuOpening;
  302. }
  303. private string CreateNewTabName(string name)
  304. {
  305. var newName = name;
  306. int i = 1;
  307. while (TabNameExists(newName))
  308. {
  309. newName = $"{name} ({i})";
  310. ++i;
  311. }
  312. return newName;
  313. }
  314. private bool TabNameExists(string name)
  315. {
  316. return _settings.Dashboards.ContainsKey(name);
  317. }
  318. /// <summary>
  319. /// Creates a new tab with a given header and adds it to <see cref="DashboardsTab"/>.
  320. /// </summary>
  321. /// <param name="header"></param>
  322. /// <returns></returns>
  323. private DynamicTabItem CreateTab(string header)
  324. {
  325. var tab = new DynamicTabItem() { Header = header };
  326. InitializeTab(tab);
  327. DashboardsTab.Items.Add(tab);
  328. return tab;
  329. }
  330. /// <summary>
  331. /// Creates a new dashboard for a tab, and then initializes the tab.
  332. /// </summary>
  333. /// <param name="tab"></param>
  334. private void InitializeNewDashboardTab(DynamicTabItem tab)
  335. {
  336. var name = CreateNewTabName("New Dashboard");
  337. _settings.Dashboards[name] = CreateForm("").SaveLayout();
  338. DashboardsTab.ChangedCommand.Execute(null);
  339. SaveSettings();
  340. tab.Header = name;
  341. InitializeTab(tab);
  342. }
  343. private void DashboardsTab_OnOnCreateTab(object sender, DynamicTabControlEventArgs args)
  344. {
  345. InitializeNewDashboardTab(args.TabItem);
  346. }
  347. private void DashboardsTab_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
  348. {
  349. if (e.OriginalSource != DashboardsTab)
  350. return;
  351. if (e.AddedItems.Count == 0)
  352. return;
  353. ShutdownDashboard();
  354. if (e.AddedItems[0] is DynamicTabItem tab)
  355. {
  356. var name = (tab.Header as string)!;
  357. if (tab!.Content == null)
  358. tab.Content = CreateDashboard(name, _settings.Dashboards[name]);
  359. else
  360. {
  361. RefreshDashboard(name);
  362. }
  363. if (IsReady)
  364. {
  365. _settings.Selected = tab.TabIndex;
  366. DashboardsTab.ChangedCommand.Execute(null);
  367. }
  368. }
  369. }
  370. private void DashboardsTab_OnOnTabsChanged(object sender, EventArgs args)
  371. {
  372. SaveSettings();
  373. }
  374. #endregion
  375. #region Dashboard & Design
  376. private void SaveDashboard(string name, DynamicFormDesignGrid grid)
  377. {
  378. _settings.Dashboards[name] = grid.Form.SaveLayout();
  379. if (IsReady)
  380. SaveSettings();
  381. }
  382. private void SaveCurrentDashboard()
  383. {
  384. var name = CurrentDashboardName;
  385. if (name == null) return;
  386. var grid = CurrentDashboard;
  387. if (grid == null) return;
  388. SaveDashboard(name, grid);
  389. }
  390. private void ShutdownDashboard(string name, DynamicFormDesignGrid grid)
  391. {
  392. SaveDashboard(name, grid);
  393. var cancel = new CancelEventArgs();
  394. foreach (var panel in _panels[grid])
  395. {
  396. panel.Shutdown(cancel);
  397. if (cancel.Cancel)
  398. {
  399. return;
  400. }
  401. }
  402. _panels[grid].Clear();
  403. }
  404. private void ShutdownDashboard()
  405. {
  406. var name = CurrentDashboardName;
  407. if (name == null) return;
  408. var grid = CurrentDashboard;
  409. if (grid == null) return;
  410. ShutdownDashboard(name, grid);
  411. }
  412. private void RefreshDashboard(string name)
  413. {
  414. if (!_dashboards.ContainsKey(name))
  415. return;
  416. var grid = _dashboards[name];
  417. if (_panels.ContainsKey(grid))
  418. {
  419. foreach (var panel in _panels[grid])
  420. panel.Refresh();
  421. }
  422. }
  423. private FrameworkElement CreateElement<TWidget, TProperties>(DynamicFormDesignGrid grid, DFLayoutElement<TProperties> element)
  424. where TWidget : FrameworkElement, IDashboardWidget<TProperties>, new()
  425. where TProperties : IConfigurationSettings, IDashboardProperties, new()
  426. {
  427. if (!_panels.ContainsKey(grid))
  428. _panels[grid] = new List<ICorePanel>();
  429. string dashboardName;
  430. if(element is CustomDashboardElement custom)
  431. {
  432. dashboardName = custom.Properties.DashboardName;
  433. }
  434. else
  435. {
  436. dashboardName = GetDashboardElements()
  437. .Where(x => x.DashboardElement == element.GetType())
  438. .FirstOrDefault()?.WidgetCaption ?? "Unknown Dashboard";
  439. }
  440. var container = DashboardContainer.Create<TWidget, TProperties>(element, dashboardName);
  441. _panels[grid].Add(container.Panel);
  442. return container;
  443. }
  444. private FrameworkElement OnCreateElement(object sender, DynamicFormCreateElementArgs e)
  445. {
  446. var method = typeof(UtilityDashboard).GetMethod(nameof(CreateElement), BindingFlags.Instance | BindingFlags.NonPublic)!;
  447. if(e.Element is CustomDashboardElement custom)
  448. {
  449. method = method.MakeGenericMethod(typeof(CustomDashboardWidget), typeof(CustomDashboardProperties));
  450. }
  451. else
  452. {
  453. var widgetType = GetVisibleDashboardElements().Where(x => x.DashboardElement == e.Element.GetType()).FirstOrDefault();
  454. if(widgetType == null)
  455. {
  456. var border = new Border
  457. {
  458. BorderBrush = new SolidColorBrush(Colors.Gray),
  459. BorderThickness = new Thickness(0.0),
  460. Margin = new Thickness(0.0),
  461. Background = ThemeManager.WorkspaceBackgroundBrush //new SolidColorBrush(Colors.Silver);
  462. };
  463. return border;
  464. }
  465. method = method.MakeGenericMethod(widgetType.Widget, widgetType.Properties);
  466. }
  467. return (method.Invoke(this, new object[] { sender, e.Element }) as FrameworkElement)!;
  468. }
  469. private static string GetCaption(Type groupType)
  470. {
  471. var caption = groupType.GetCustomAttribute<Caption>();
  472. if(caption != null)
  473. {
  474. return caption.Text;
  475. }
  476. return CoreUtils.Neatify(groupType.Name);
  477. }
  478. private static List<WidgetDashboardElement> GetDashboardElements()
  479. {
  480. if (_dashboardElements == null)
  481. {
  482. _dashboardElements = new();
  483. var types = CoreUtils.Entities.Where(x => x.IsClass && !x.IsGenericType && x.GetInterfaces().Contains(typeof(IDashboardElement)));
  484. foreach (var type in types)
  485. {
  486. var dashboardElementDef = type.GetSuperclassDefinition(typeof(DashboardElement<,,>));
  487. if (dashboardElementDef != null)
  488. {
  489. var dashboard = dashboardElementDef.GenericTypeArguments[0];
  490. var group = dashboardElementDef.GenericTypeArguments[1];
  491. var properties = dashboardElementDef.GenericTypeArguments[2];
  492. var requires = dashboard.GetInterfaces(typeof(IRequiresSecurity<>)).Select(x => x.GenericTypeArguments[0]);
  493. _dashboardElements.Add(new(type, dashboard, group, properties, requires.ToArray()));
  494. }
  495. }
  496. }
  497. return _dashboardElements;
  498. }
  499. private static IEnumerable<WidgetDashboardElement> GetVisibleDashboardElements()
  500. {
  501. return GetDashboardElements().Where(x =>
  502. {
  503. foreach (var require in x.SecurityTokens)
  504. {
  505. if (!Security.IsAllowed(require))
  506. return false;
  507. }
  508. return true;
  509. });
  510. }
  511. private void UpdateCustomDashboardList()
  512. {
  513. var customDashboards = new GlobalConfiguration<GlobalUtilityDashboardSettings>().Load().CustomDashboards;
  514. foreach(var grid in _dashboards.Values)
  515. {
  516. grid.ClearElementTypesAndActions();
  517. AddCustomDashboardsToGrid(grid, customDashboards);
  518. }
  519. }
  520. private void AddCustomDashboardsToGrid(DynamicFormDesignGrid grid, List<CustomDashboard> customDashboards)
  521. {
  522. foreach(var widget in GetVisibleDashboardElements())
  523. {
  524. grid.AddElementType(widget.DashboardElement, widget.WidgetCaption, widget.GroupCaption, true);
  525. }
  526. foreach(var customDashboard in customDashboards)
  527. {
  528. grid.AddElementType(typeof(CustomDashboardElement), customDashboard.Name, customDashboard.Group.NotWhiteSpaceOr("Custom"), customDashboard, AddCustom_Click, allowduplicate: true);
  529. }
  530. grid.AddElementAction<object?>("Create New", InABox.Wpf.Resources.add, "", null, CreateNewCustom_Click);
  531. }
  532. private Border CreateDashboard(string name, string layout)
  533. {
  534. var form = CreateForm(layout);
  535. var grid = new DynamicFormDesignGrid();
  536. var customDashboards = new GlobalConfiguration<GlobalUtilityDashboardSettings>().Load().CustomDashboards;
  537. AddCustomDashboardsToGrid(grid, customDashboards);
  538. grid.ShowBorders = false;
  539. grid.OnCreateElement += OnCreateElement;
  540. grid.OnAfterDesign += OnAfterDesign;
  541. grid.OnAfterRender += OnAfterRender;
  542. grid.CustomiseElementContextMenu += Grid_CustomiseElementContextMenu;
  543. grid.Mode = FormMode.Preview;
  544. var border = new Border
  545. {
  546. BorderBrush = new SolidColorBrush(Colors.Silver),
  547. BorderThickness = new Thickness(0.75),
  548. Child = grid // scroll;
  549. };
  550. _dashboards[name] = grid;
  551. _panels[grid] = new List<ICorePanel>();
  552. grid.Form = form;
  553. grid.Initialize();
  554. return border;
  555. }
  556. private void Grid_CustomiseElementContextMenu(ContextMenu menu, DFLayoutElement element)
  557. {
  558. if(element is CustomDashboardElement dashboardElement)
  559. {
  560. menu.AddItem("Edit Dashboard", null, dashboardElement, EditDashboard_Click);
  561. }
  562. }
  563. private void EditDashboard_Click(CustomDashboardElement element)
  564. {
  565. var config = new GlobalConfiguration<GlobalUtilityDashboardSettings>();
  566. var settings = config.Load();
  567. var customDashboard = settings.CustomDashboards.FirstOrDefault(x => x.Name == element.Properties.DashboardName);
  568. if(customDashboard is null)
  569. {
  570. return;
  571. }
  572. var dashboard = DynamicDashboardUtils.Deserialize(customDashboard.Layout);
  573. if(dashboard is null)
  574. {
  575. return;
  576. }
  577. var editor = new DynamicDashboardEditor(dashboard);
  578. editor.DashboardName = customDashboard.Name;
  579. editor.DashboardGroup = customDashboard.Group;
  580. var dlg = new DynamicContentDialog(editor)
  581. {
  582. Title = "Edit dashboard",
  583. SizeToContent = SizeToContent.Height,
  584. CanSave = true
  585. };
  586. if(dlg.ShowDialog() == true)
  587. {
  588. customDashboard.Layout = DynamicDashboardUtils.Serialize(editor.GetDashboard());
  589. customDashboard.Name = editor.DashboardName;
  590. customDashboard.Group = editor.DashboardGroup;
  591. config.Save(settings);
  592. element.Properties = new CustomDashboardProperties
  593. {
  594. DashboardName = editor.DashboardName
  595. };
  596. UpdateCustomDashboardList();
  597. }
  598. }
  599. private DFLayoutElement AddCustom_Click(CustomDashboard dashboard)
  600. {
  601. var element = new CustomDashboardElement();
  602. element.Properties = new CustomDashboardProperties
  603. {
  604. DashboardName = dashboard.Name
  605. };
  606. return element;
  607. }
  608. private DFLayoutElement? CreateNewCustom_Click(object? tag)
  609. {
  610. var dashboard = new DynamicDashboard();
  611. var editor = new DynamicDashboardEditor(dashboard);
  612. editor.DashboardName = "New Dashboard";
  613. editor.DashboardGroup = "Custom";
  614. var dlg = new DynamicContentDialog(editor)
  615. {
  616. Title = "Create new dashboard",
  617. SizeToContent = SizeToContent.Height,
  618. CanSave = true
  619. };
  620. if(dlg.ShowDialog() == true)
  621. {
  622. var config = new GlobalConfiguration<GlobalUtilityDashboardSettings>();
  623. var settings = config.Load();
  624. settings.CustomDashboards.Add(new CustomDashboard
  625. {
  626. Layout = DynamicDashboardUtils.Serialize(editor.GetDashboard()),
  627. Name = editor.DashboardName,
  628. Group = editor.DashboardGroup
  629. });
  630. config.Save(settings);
  631. var element = new CustomDashboardElement();
  632. element.Properties = new CustomDashboardProperties
  633. {
  634. DashboardName = editor.DashboardName
  635. };
  636. UpdateCustomDashboardList();
  637. return element;
  638. }
  639. else
  640. {
  641. return null;
  642. }
  643. }
  644. private void OnAfterRender(DynamicFormDesignGrid sender)
  645. {
  646. if (!sender.IsDesigning)
  647. {
  648. if (_panels.TryGetValue(sender, out var panels))
  649. {
  650. foreach (var panel in panels)
  651. panel.Refresh();
  652. }
  653. }
  654. }
  655. private static DFLayout CreateForm(string layout)
  656. {
  657. var form = new DFLayout();
  658. if (string.IsNullOrWhiteSpace(layout))
  659. {
  660. form.ColumnWidths.Add("*");
  661. form.ColumnWidths.Add("*");
  662. form.ColumnWidths.Add("*");
  663. form.RowHeights.Add("*");
  664. form.RowHeights.Add("*");
  665. form.RowHeights.Add("*");
  666. }
  667. else
  668. {
  669. form.LoadLayout(layout);
  670. }
  671. return form;
  672. }
  673. private void OnAfterDesign(object sender)
  674. {
  675. SaveCurrentDashboard();
  676. if(CurrentDashboardName is string name) // Null-check
  677. {
  678. RefreshDashboard(name);
  679. }
  680. }
  681. #endregion
  682. }
  683. }