123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- using InABox.Clients;
- using InABox.Core;
- using InABox.Scripting;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics.CodeAnalysis;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace InABox.Wpf.Dashboard;
- public interface IDynamicDashboardTable
- {
- string Key { get; set; }
- IEnumerable<CoreColumn> CoreColumns { get; }
- }
- public interface IDynamicDashboardDataQuery : IDynamicDashboardTable
- {
- Type Type { get; }
- IFilter? Filter { get; set; }
- IColumns Columns { get; set; }
- ISortOrder? SortOrder { get; set; }
- IEnumerable<CoreColumn> IDynamicDashboardTable.CoreColumns => Columns.Columns().Select(x => new CoreColumn
- {
- ColumnName = x.Name,
- DataType = x.Type
- });
- }
- public class DynamicDashboardDataQuery<T> : IDynamicDashboardDataQuery
- where T : Entity, IRemotable, new()
- {
- public string Key { get; set; } = typeof(T).Name;
- public Filter<T>? Filter { get; set; }
- public Columns<T> Columns { get; set; } = Core.Columns.None<T>();
- public SortOrder<T>? SortOrder { get; set; } = null;
- #region IDynamicDashboardDataQuery
- Type IDynamicDashboardDataQuery.Type => typeof(T);
- IFilter? IDynamicDashboardDataQuery.Filter
- {
- get => Filter;
- set => Filter = value as Filter<T>;
- }
- IColumns IDynamicDashboardDataQuery.Columns
- {
- get => Columns;
- set => Columns = (value as Columns<T>) ?? Core.Columns.None<T>();
- }
- ISortOrder? IDynamicDashboardDataQuery.SortOrder
- {
- get => SortOrder;
- set => SortOrder = value as SortOrder<T>;
- }
- #endregion
- }
- public class DynamicDashboardAdditionalTable : IDynamicDashboardTable
- {
- public string Key { get; set; } = "";
- public List<CoreColumn> Columns { get; set; } = new();
- private string? _script;
- public string? Script
- {
- get => _script;
- set
- {
- if(_script != value)
- {
- _script = value;
- _scriptDocument = null;
- }
- }
- }
- IEnumerable<CoreColumn> IDynamicDashboardTable.CoreColumns => Columns;
- private ScriptDocument? _scriptDocument;
- private ScriptDocument? ScriptDocument
- {
- get
- {
- if(_scriptDocument is null && Script is not null)
- {
- _scriptDocument = new(Script);
- _scriptDocument.Compile();
- }
- return _scriptDocument;
- }
- }
- public static string DefaultScript()
- {
- return @"using InABox.Wpf.Dashboard;
- public class Module
- {
- public void PopulateTable(CoreTable table, DynamicDashboardData data)
- {
- // Populate 'table' using the data from 'data'.
- }
- }";
- }
- public void PopulateTable(CoreTable table, DynamicDashboardData data)
- {
- if (ScriptDocument is null) return;
- ScriptDocument.Execute(methodname: "PopulateTable", parameters: [table, data]);
- }
- }
- public class DynamicDashboardDataComponent
- {
- public List<IDynamicDashboardDataQuery> Queries { get; set; } = new();
- public List<DynamicDashboardAdditionalTable> AdditionalTables { get; set; } = new();
- public IEnumerable<IDynamicDashboardTable> Tables => Queries.Concat<IDynamicDashboardTable>(AdditionalTables);
- public IDynamicDashboardTable GetTable(string key)
- {
- return Tables.FirstOrDefault(x => x.Key == key)
- ?? throw new KeyNotFoundException($"Data table '{key}' does not exist.");
- }
- public bool TryGetTable(string key, [NotNullWhen(true)] out IDynamicDashboardTable? query)
- {
- query = Tables.FirstOrDefault(x => x.Key == key);
- return query != null;
- }
- private void PopulateAdditionalTables(DynamicDashboardData data)
- {
- foreach(var tableDef in AdditionalTables)
- {
- var table = new CoreTable();
- table.Columns.AddRange(tableDef.Columns);
- tableDef.PopulateTable(table, data);
- data.Data.Add(tableDef.Key, table);
- }
- }
- /// <summary>
- /// Run the query to get the data according to the definitions of <see cref="Queries"/>.
- /// </summary>
- /// <param name="maxRecords">Set to a non-<see langword="null"/> value to limit the number of records returned. Used for preview mode.</param>
- public DynamicDashboardData RunQuery(int? maxRecords = null)
- {
- var range = maxRecords.HasValue ? CoreRange.Database(maxRecords.Value) : null;
- var queryDefs = Queries.Select(x => new KeyedQueryDef(x.Key, x.Type, x.Filter, x.Columns, x.SortOrder, range));
- var results = Client.QueryMultiple(queryDefs);
- var data = new DynamicDashboardData(results.Results);
- PopulateAdditionalTables(data);
- return data;
- }
- /// <summary>
- /// Run the query asynchronously to get the data according to the definitions of <see cref="Queries"/>.
- /// </summary>
- /// <param name="maxRecords">Set to a non-<see langword="null"/> value to limit the number of records returned. Used for preview mode.</param>
- public async Task<DynamicDashboardData> RunQueryAsync(int? maxRecords = null)
- {
- var range = maxRecords.HasValue ? CoreRange.Database(maxRecords.Value) : null;
- var queryDefs = Queries.Select(x => new KeyedQueryDef(x.Key, x.Type, x.Filter, x.Columns, x.SortOrder, range));
- var results = await Client.QueryMultipleAsync(queryDefs);
- var data = new DynamicDashboardData(results.Results);
- PopulateAdditionalTables(data);
- return data;
- }
- }
- public class DynamicDashboardData(Dictionary<string, CoreTable> data)
- {
- public Dictionary<string, CoreTable> Data { get; set; } = data;
- public bool TryGetData(string key, [NotNullWhen(true)] out CoreTable? query)
- {
- return Data.TryGetValue(key, out query);
- }
- }
|