using InABox.Core; using InABox.DynamicGrid; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace InABox.Wpf.Dashboard.Editor; internal class DynamicDashboardDataQueryEditItem : BaseObject { // Having to do custom OnPropertyChanged stuff because Fody isn't allowed in this project. private Type? _type; [ComboLookupEditor(typeof(TypeLookupGenerator))] [EditorSequence(1)] public Type? Type { get => _type; set { var oldValue = _type; _type = value; OnPropertyChanged(nameof(Type), oldValue, value); } } [EditorSequence(2)] public string Name { get; set; } = ""; [FilterEditor] [EditorSequence(3)] public string Filter { get; set; } = ""; [ColumnsEditor] [EditorSequence(4)] public string Columns { get; set; } = ""; [SortOrderEditor] [EditorSequence(5)] public string SortOrder { get; set; } = ""; public DynamicDashboardDataQueryEditItem() { } public DynamicDashboardDataQueryEditItem(IDynamicDashboardDataQuery query) { Name = query.Key; Type = query.Type; Filter = Serialization.Serialize(query.Filter); Columns = Serialization.Serialize(query.Columns); SortOrder = Serialization.Serialize(query.SortOrder); } private class TypeLookupGenerator : LookupGenerator { public TypeLookupGenerator(DynamicDashboardDataQueryEditItem[]? items) : base(items) { } protected override void DoGenerateLookups() { foreach(var entity in CoreUtils.Entities.Where(x => x.IsSubclassOf(typeof(Entity)) && x.HasInterface()).OrderBy(x => x.Name)) { AddValue(entity, entity.Name); } } } protected override void DoPropertyChanged(string name, object? before, object? after) { base.DoPropertyChanged(name, before, after); if(name == nameof(Type)) { Filter = ""; Columns = ""; SortOrder = ""; if (Type is not null && (Name.IsNullOrWhiteSpace() || Name == (before as Type)?.Name)) { Name = Type.Name; } } } public IDynamicDashboardDataQuery? ToQuery() { if(Type is not null) { var query = (Activator.CreateInstance(typeof(DynamicDashboardDataQuery<>).MakeGenericType(Type)) as IDynamicDashboardDataQuery)!; query.Key = Name; query.Filter = Serialization.Deserialize(typeof(Filter<>).MakeGenericType(Type), Filter) as IFilter; query.Columns = (Serialization.Deserialize(typeof(Columns<>).MakeGenericType(Type), Columns) as IColumns) ?? Core.Columns.None(Type); query.SortOrder = Serialization.Deserialize(typeof(SortOrder<>).MakeGenericType(Type), SortOrder) as ISortOrder; return query; } else { return null; } } } internal class DynamicDashboardDataQueryGrid : DynamicItemsListGrid { protected override void Init() { base.Init(); ActionColumns.Add(new DynamicTextColumn(GetText) { HeaderText = "Table" }); HiddenColumns.Add(x => x.Type); } private object? GetText(CoreRow? row) { return row?.Get(x => x.Type)?.Name ?? ""; } protected override void DoValidate(DynamicDashboardDataQueryEditItem[] items, List errors) { base.DoValidate(items, errors); foreach(var item in items) { if(Items.Any(x => x != item && x.Name == item.Name)) { errors.Add($"Duplicate key '{item.Name}'"); } } } protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.AddRows = true; options.EditRows = true; options.DeleteRows = true; } private readonly Column FilterColumn = new(x => x.Filter); private readonly Column ColumnsColumn = new(x => x.Columns); private readonly Column SortOrderColumn = new(x => x.SortOrder); private readonly Column TypeColumn = new(x => x.Type); protected override void CustomiseEditor(IDynamicEditorForm form, DynamicDashboardDataQueryEditItem[] items, DynamicGridColumn column, BaseEditor editor) { base.CustomiseEditor(form, items, column, editor); var item = items.First(); if(FilterColumn.IsEqualTo(column.ColumnName) && editor is FilterEditor filterEditor) { filterEditor.Type = item.Type; } else if(ColumnsColumn.IsEqualTo(column.ColumnName) && editor is ColumnsEditor columnsEditor) { columnsEditor.Type = item.Type; } else if(SortOrderColumn.IsEqualTo(column.ColumnName) && editor is SortOrderEditor sortEditor) { sortEditor.Type = item.Type; } } protected override Dictionary EditorValueChanged(IDynamicEditorForm editor, DynamicDashboardDataQueryEditItem[] items, string name, object value) { var changed = base.EditorValueChanged(editor, items, name, value); if (TypeColumn.IsEqualTo(name)) { if(value is Type type) { if(editor.TryFindEditor(FilterColumn.Property, out var filterEditor)) { filterEditor.FilterType = type; } if(editor.TryFindEditor(ColumnsColumn.Property, out var columnsEditor)) { columnsEditor.ColumnsType = type; } } } return changed; } }