using InABox.Clients; using InABox.Core; 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 CoreColumns { get; } } public interface IDynamicDashboardDataQuery : IDynamicDashboardTable { Type Type { get; } IFilter? Filter { get; set; } IColumns Columns { get; set; } ISortOrder? SortOrder { get; set; } IEnumerable IDynamicDashboardTable.CoreColumns => Columns.Columns().Select(x => new CoreColumn { ColumnName = x.Name, DataType = x.Type }); } public class DynamicDashboardDataQuery : IDynamicDashboardDataQuery where T : Entity, IRemotable, new() { public string Key { get; set; } = typeof(T).Name; public Filter? Filter { get; set; } public Columns Columns { get; set; } = Core.Columns.None(); public SortOrder? SortOrder { get; set; } = null; #region IDynamicDashboardDataQuery Type IDynamicDashboardDataQuery.Type => typeof(T); IFilter? IDynamicDashboardDataQuery.Filter { get => Filter; set => Filter = value as Filter; } IColumns IDynamicDashboardDataQuery.Columns { get => Columns; set => Columns = (value as Columns) ?? Core.Columns.None(); } ISortOrder? IDynamicDashboardDataQuery.SortOrder { get => SortOrder; set => SortOrder = value as SortOrder; } #endregion } public class DynamicDashboardAdditionalTable : IDynamicDashboardTable { public string Key { get; set; } = ""; public List Columns { get; set; } = new(); public string? Script { get; set; } IEnumerable IDynamicDashboardTable.CoreColumns => Columns; 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 class DynamicDashboardDataComponent { public List Queries { get; set; } = new(); public List AdditionalTables { get; set; } = new(); public IEnumerable Tables => Queries.Concat(AdditionalTables); public IDynamicDashboardTable GetTable(string key) { return Tables.FirstOrDefault(x => x.Key == key) ?? throw new KeyNotFoundException($"Data query '{key}' does not exist."); } public bool TryGetTable(string key, [NotNullWhen(true)] out IDynamicDashboardTable? query) { query = Tables.FirstOrDefault(x => x.Key == key); return query != null; } public IDynamicDashboardDataQuery GetQuery(string key) { return Queries.FirstOrDefault(x => x.Key == key) ?? throw new KeyNotFoundException($"Data query '{key}' does not exist."); } public bool TryGetQuery(string key, [NotNullWhen(true)] out IDynamicDashboardDataQuery? query) { query = Queries.FirstOrDefault(x => x.Key == key); return query != null; } /// /// Run the query to get the data according to the definitions of . /// /// Set to a non- value to limit the number of records returned. Used for preview mode. 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); return new DynamicDashboardData(results.Results); } /// /// Run the query asynchronously to get the data according to the definitions of . /// /// Set to a non- value to limit the number of records returned. Used for preview mode. public async Task 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); return new DynamicDashboardData(results.Results); } } public class DynamicDashboardData(Dictionary data) { public Dictionary Data { get; set; } = data; public bool TryGetData(string key, [NotNullWhen(true)] out CoreTable? query) { return Data.TryGetValue(key, out query); } }