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);
}
}