using InABox.Core; using InABox.DynamicGrid; using InABox.Wpf.Dashboard.Editor; using InABox.WPF; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace InABox.Wpf.Dashboard; public class DynamicDashboardGridPresenterProperties : BaseObject { /// /// The key of the query that will provide the data for this presenter. /// public string Table { get; set; } = ""; public DynamicGridColumns? Columns { get; set; } } [Caption("Grid")] public class DynamicDashboardGridPresenter : IDynamicDashboardDataPresenter { public DynamicDashboardGridPresenterProperties Properties { get; set; } = null!; private DynamicDashboardDataComponent _dataComponent = null!; public DynamicDashboardDataComponent DataComponent { get => _dataComponent; set { _dataComponent = value; UpdateData(); } } public int PreviewHeight => 300; public bool IsPreview { get; set; } private CoreTableGrid? Grid; private readonly ContentControl Content = new(); private DynamicDashboardData? _data; public FrameworkElement? Setup() { UpdateData(); return Content; } private void UpdateData() { if (Properties.Table.IsNullOrWhiteSpace() || !DataComponent.TryGetTable(Properties.Table, out var table)) { Properties.Table = DataComponent.Tables.FirstOrDefault()?.Key ?? ""; } if (!DataComponent.TryGetTable(Properties.Table, out table)) { var border = new Border { Background = Colors.DimGray.ToBrush() }; border.ContextMenuOpening += Border_ContextMenuOpening; Content.Content = border; return; } Grid = new DataGrid(this) { ColumnSchema = new DataGridColumnSchema(this) }; Grid.Refresh(true, false); Content.Content = Grid as FrameworkElement; } private void CustomiseMenu(ContextMenu menu) { if (!IsPreview) return; var tableItem = menu.AddItem("Select Table", null, null); foreach(var table in DataComponent.Tables) { tableItem.AddCheckMenuItem(table.Key, table.Key, SelectTable_Click, isChecked: Properties.Table == table.Key); } if(tableItem.Items.Count <= 1) { menu.Items.Remove(tableItem); } menu.AddItem("Select Data", null, SelectData_Click); } private void SelectData_Click() { if (DynamicDashboardDataEditor.Execute(DataComponent)) { UpdateData(); DataComponent.RunQueryAsync(100).ContinueWith(data => { if(data.Exception is not null) { MessageWindow.ShowError("Error loading data.", data.Exception); } else { Refresh(data.Result); } }, TaskScheduler.FromCurrentSynchronizationContext()); } } private void SelectTable_Click(string key, bool isChecked) { if (!isChecked) return; Properties.Table = key; Properties.Columns = null; UpdateData(); if(_data is not null) { Refresh(_data); } } private void Border_ContextMenuOpening(object sender, ContextMenuEventArgs e) { var menu = new ContextMenu(); CustomiseMenu(menu); menu.IsOpen = true; e.Handled = true; } public void Refresh(DynamicDashboardData data) { _data = data; if (!DataComponent.TryGetTable(Properties.Table, out var _table) || Grid is null) { return; } if(data.TryGetData(Properties.Table, out var table)) { Grid.Table = table; } else { Grid.Table.Rows.Clear(); } Grid.Refresh(false, true); } public void Shutdown(CancelEventArgs? cancel) { } private class DataGridColumnSchema(DynamicDashboardGridPresenter presenter) : IDynamicGridColumnSchema { public IEnumerable ColumnNames { get { if (presenter.DataComponent.TryGetTable(presenter.Properties.Table, out var table)) { return table.GetColumns(presenter.DataComponent).Where(x => EditorUtils.GetEditor(x.DataType) is not null).Select(x => x.ColumnName); } else { return []; } } } public DynamicGridColumn GetColumn(string column) { var table = presenter.DataComponent.GetTable(presenter.Properties.Table); var coreCol = table.GetColumns(presenter.DataComponent).First(x => x.ColumnName == column); return DynamicGridColumn.FromCoreColumn(coreCol)!; } public string? GetComment(string column) { return null; } public bool IsVisible(string column) { return true; } } private class DataGrid(DynamicDashboardGridPresenter presenter) : CoreTableGrid { protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.SelectColumns = true; } public override DynamicGridColumns GenerateColumns() { if(presenter.Properties.Columns is not null) { var columns = new DynamicGridColumns(); columns.AddRange(presenter.Properties.Columns.Select(x => x.Copy())); return columns; } else { return base.GenerateColumns(); } } protected override void LoadColumnsMenu(ContextMenu menu) { base.LoadColumnsMenu(menu); menu.AddSeparatorIfNeeded(); presenter.CustomiseMenu(menu); menu.RemoveUnnecessarySeparators(); } protected override void SaveColumns(DynamicGridColumns columns) { base.SaveColumns(columns); presenter.Properties.Columns = columns.Count > 0 ? columns : null; } protected override DynamicGridColumns LoadColumns() { return presenter.Properties.Columns ?? base.LoadColumns(); } } }