DynamicDashboardDataComponent.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. using InABox.Clients;
  2. using InABox.Core;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. namespace InABox.Wpf.Dashboard;
  10. public interface IDynamicDashboardTable
  11. {
  12. string Key { get; set; }
  13. IEnumerable<CoreColumn> CoreColumns { get; }
  14. }
  15. public interface IDynamicDashboardDataQuery : IDynamicDashboardTable
  16. {
  17. Type Type { get; }
  18. IFilter? Filter { get; set; }
  19. IColumns Columns { get; set; }
  20. ISortOrder? SortOrder { get; set; }
  21. IEnumerable<CoreColumn> IDynamicDashboardTable.CoreColumns => Columns.Columns().Select(x => new CoreColumn
  22. {
  23. ColumnName = x.Name,
  24. DataType = x.Type
  25. });
  26. }
  27. public class DynamicDashboardDataQuery<T> : IDynamicDashboardDataQuery
  28. where T : Entity, IRemotable, new()
  29. {
  30. public string Key { get; set; } = typeof(T).Name;
  31. public Filter<T>? Filter { get; set; }
  32. public Columns<T> Columns { get; set; } = Core.Columns.None<T>();
  33. public SortOrder<T>? SortOrder { get; set; } = null;
  34. #region IDynamicDashboardDataQuery
  35. Type IDynamicDashboardDataQuery.Type => typeof(T);
  36. IFilter? IDynamicDashboardDataQuery.Filter
  37. {
  38. get => Filter;
  39. set => Filter = value as Filter<T>;
  40. }
  41. IColumns IDynamicDashboardDataQuery.Columns
  42. {
  43. get => Columns;
  44. set => Columns = (value as Columns<T>) ?? Core.Columns.None<T>();
  45. }
  46. ISortOrder? IDynamicDashboardDataQuery.SortOrder
  47. {
  48. get => SortOrder;
  49. set => SortOrder = value as SortOrder<T>;
  50. }
  51. #endregion
  52. }
  53. public class DynamicDashboardAdditionalTable : IDynamicDashboardTable
  54. {
  55. public string Key { get; set; } = "";
  56. public List<CoreColumn> Columns { get; set; } = new();
  57. public string? Script { get; set; }
  58. IEnumerable<CoreColumn> IDynamicDashboardTable.CoreColumns => Columns;
  59. public static string DefaultScript()
  60. {
  61. return @"using InABox.Wpf.Dashboard;
  62. public class Module
  63. {
  64. public void PopulateTable(CoreTable table, DynamicDashboardData data)
  65. {
  66. // Populate 'table' using the data from 'data'.
  67. }
  68. }";
  69. }
  70. }
  71. public class DynamicDashboardDataComponent
  72. {
  73. public List<IDynamicDashboardDataQuery> Queries { get; set; } = new();
  74. public List<DynamicDashboardAdditionalTable> AdditionalTables { get; set; } = new();
  75. public IEnumerable<IDynamicDashboardTable> Tables => Queries.Concat<IDynamicDashboardTable>(AdditionalTables);
  76. public IDynamicDashboardTable GetTable(string key)
  77. {
  78. return Tables.FirstOrDefault(x => x.Key == key)
  79. ?? throw new KeyNotFoundException($"Data query '{key}' does not exist.");
  80. }
  81. public bool TryGetTable(string key, [NotNullWhen(true)] out IDynamicDashboardTable? query)
  82. {
  83. query = Tables.FirstOrDefault(x => x.Key == key);
  84. return query != null;
  85. }
  86. public IDynamicDashboardDataQuery GetQuery(string key)
  87. {
  88. return Queries.FirstOrDefault(x => x.Key == key)
  89. ?? throw new KeyNotFoundException($"Data query '{key}' does not exist.");
  90. }
  91. public bool TryGetQuery(string key, [NotNullWhen(true)] out IDynamicDashboardDataQuery? query)
  92. {
  93. query = Queries.FirstOrDefault(x => x.Key == key);
  94. return query != null;
  95. }
  96. /// <summary>
  97. /// Run the query to get the data according to the definitions of <see cref="Queries"/>.
  98. /// </summary>
  99. /// <param name="maxRecords">Set to a non-<see langword="null"/> value to limit the number of records returned. Used for preview mode.</param>
  100. public DynamicDashboardData RunQuery(int? maxRecords = null)
  101. {
  102. var range = maxRecords.HasValue ? CoreRange.Database(maxRecords.Value) : null;
  103. var queryDefs = Queries.Select(x => new KeyedQueryDef(x.Key, x.Type, x.Filter, x.Columns, x.SortOrder, range));
  104. var results = Client.QueryMultiple(queryDefs);
  105. return new DynamicDashboardData(results.Results);
  106. }
  107. /// <summary>
  108. /// Run the query asynchronously to get the data according to the definitions of <see cref="Queries"/>.
  109. /// </summary>
  110. /// <param name="maxRecords">Set to a non-<see langword="null"/> value to limit the number of records returned. Used for preview mode.</param>
  111. public async Task<DynamicDashboardData> RunQueryAsync(int? maxRecords = null)
  112. {
  113. var range = maxRecords.HasValue ? CoreRange.Database(maxRecords.Value) : null;
  114. var queryDefs = Queries.Select(x => new KeyedQueryDef(x.Key, x.Type, x.Filter, x.Columns, x.SortOrder, range));
  115. var results = await Client.QueryMultipleAsync(queryDefs);
  116. return new DynamicDashboardData(results.Results);
  117. }
  118. }
  119. public class DynamicDashboardData(Dictionary<string, CoreTable> data)
  120. {
  121. public Dictionary<string, CoreTable> Data { get; set; } = data;
  122. public bool TryGetData(string key, [NotNullWhen(true)] out CoreTable? query)
  123. {
  124. return Data.TryGetValue(key, out query);
  125. }
  126. }