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 Query { 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; private IDynamicDashboardGridPresenterGrid? Grid; private readonly ContentControl Content = new(); private DynamicDashboardData? _data; public FrameworkElement? Setup() { UpdateData(); return Content; } private void UpdateData() { if (Properties.Query.IsNullOrWhiteSpace() || !DataComponent.TryGetQuery(Properties.Query, out var query)) { Properties.Query = DataComponent.Queries.FirstOrDefault()?.Key ?? ""; } if (!DataComponent.TryGetQuery(Properties.Query, out query)) { var border = new Border { Background = Colors.DimGray.ToBrush() }; border.ContextMenuOpening += Border_ContextMenuOpening; Content.Content = border; return; } Grid = (Activator.CreateInstance(typeof(DynamicDashboardGridPresenterGrid<>).MakeGenericType(query.Type)) as IDynamicDashboardGridPresenterGrid)!; Grid.OnGenerateColumns += Grid_OnGenerateColumns; Grid.OnSaveColumns += Grid_OnSaveColumns; Grid.GetAvailableColumns += Grid_GetAvailableColumns; Grid.OnLoadColumnsMenu += Grid_OnLoadColumnsMenu; Grid.Refresh(true, false); Content.Content = Grid as FrameworkElement; } private void CustomiseMenu(ContextMenu menu) { if(DataComponent.Queries.Count > 1) { var queryItem = menu.AddItem("Select Query", null, null); foreach(var query in DataComponent.Queries) { queryItem.AddCheckMenuItem(query.Key, query.Key, SelectQuery_Click, isChecked: Properties.Query == query.Key); } } 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 SelectQuery_Click(string key, bool isChecked) { if (!isChecked) return; Properties.Query = key; Properties.Columns = null; UpdateData(); if(_data is not null) { Refresh(_data); } } private void Grid_OnLoadColumnsMenu(ContextMenu menu) { menu.AddSeparatorIfNeeded(); CustomiseMenu(menu); menu.RemoveUnnecessarySeparators(); } private void Grid_GetAvailableColumns(GetAvailableColumnsEventArgs args) { if (!DataComponent.TryGetQuery(Properties.Query, out var query)) { return; } args.Columns = args.Columns.Where(x => query.Columns.Contains(x.ColumnName)); } private void Border_ContextMenuOpening(object sender, ContextMenuEventArgs e) { var menu = new ContextMenu(); CustomiseMenu(menu); menu.IsOpen = true; e.Handled = true; } private void Grid_OnSaveColumns(object sender, SaveColumnsEventArgs args) { Properties.Columns = args.Columns.Count > 0 ? args.Columns : null; } private void Grid_OnGenerateColumns(object sender, GenerateColumnsEventArgs args) { if(Properties.Columns is not null) { args.Columns.Clear(); foreach(var column in Properties.Columns) { args.Columns.Add(column.Copy()); } } else if (DataComponent.TryGetQuery(Properties.Query, out var query) && Grid is not null) { args.Columns.Clear(); args.Columns.AddRange(Grid.ExtractColumns(query.Columns)); } } public void Refresh(DynamicDashboardData data) { _data = data; if (!DataComponent.TryGetQuery(Properties.Query, out var query) || Grid is null) { return; } if(data.TryGetData(Properties.Query, out var table)) { Grid.Items.Clear(); foreach(var obj in table.ToObjects(query.Type)) { Grid.Items.Add(obj); } } else { Grid.Items.Clear(); } Grid.Refresh(false, true); } public void Shutdown(CancelEventArgs? cancel) { } } internal interface IDynamicDashboardGridPresenterGrid : IDynamicItemsListGrid { public event Action? OnLoadColumnsMenu; } internal class DynamicDashboardGridPresenterGrid : DynamicItemsListGrid, IDynamicDashboardGridPresenterGrid where T : BaseObject, new() { public event Action? OnLoadColumnsMenu; protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.Clear(); options.SelectColumns = true; } protected override void LoadColumnsMenu(ContextMenu menu) { base.LoadColumnsMenu(menu); OnLoadColumnsMenu?.Invoke(menu); } }