123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- using Comal.Classes;
- using InABox.Clients;
- using InABox.Core;
- using InABox.DynamicGrid;
- using InABox.WPF;
- using PRS.Shared.Events;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- namespace PRS.Shared;
- public class EventGrid : DynamicDataGrid<Event>
- {
- private readonly BitmapImage _email = InABox.Wpf.Resources.email.AsBitmapImage();
- private readonly BitmapImage _notification = InABox.Wpf.Resources.notification.AsBitmapImage();
- private readonly BitmapImage _edit = InABox.Wpf.Resources.pencil.AsBitmapImage();
- private Button? EnableButton = null;
- private Dictionary<Guid, EventSubscriberType> _subscribedSet = new();
- public Guid EmployeeID { get; set; }
- protected override void Init()
- {
- base.Init();
- HiddenColumns.Add(x => x.Data);
- HiddenColumns.Add(x => x.Enabled);
- HiddenColumns.Add(x => x.Visible);
- ActionColumns.Add(new DynamicMenuColumn(BuildMenu, getImage: Menu_GetImage) { ToolTip = Subscribed_ToolTip });
- if (Security.IsAllowed<CanManageEvents>())
- {
- ActionColumns.Add(new DynamicImageColumn(_edit, Edit_Click));
- EnableButton = AddButton("Disable", null, Enable_Click);
- EnableButton.Visibility = Visibility.Collapsed;
- }
- }
- protected override void SelectItems(CoreRow[]? rows)
- {
- base.SelectItems(rows);
- if(EnableButton is not null)
- {
- if(rows is not null && rows.Length > 0)
- {
- EnableButton.Visibility = Visibility.Visible;
- EnableButton.Content = rows.Any(x => !x.Get<Event, bool>(x => x.Enabled))
- ? "Enable" : "Disable";
- }
- else
- {
- EnableButton.Visibility = Visibility.Collapsed;
- }
- }
- }
- private bool Enable_Click(Button button, CoreRow[] rows)
- {
- var items = LoadItems(rows);
- if(items.Any(x => !x.Enabled))
- {
- foreach(var item in items)
- {
- item.Enabled = true;
- }
- Client.Save(items, "Event enabled.");
- return true;
- }
- else
- {
- foreach(var item in items)
- {
- item.Enabled = false;
- }
- Client.Save(items, "Event disabled.");
- return true;
- }
- }
- #region UIComponent
- private class UIComponent : DynamicGridGridUIComponent<Event>
- {
- protected override Brush? GetCellBackground(CoreRow row, DynamicColumnBase column)
- {
- if(row.Get<Event, bool>(x => x.Enabled))
- {
- return null;
- }
- else
- {
- return Colors.Gainsboro.ToBrush(0.5);
- }
- }
- }
- protected override IDynamicGridUIComponent CreateUIComponent()
- {
- return new UIComponent { Parent = this };
- }
- #endregion
- protected override void DoReconfigure(DynamicGridOptions options)
- {
- base.DoReconfigure(options);
- if (Security.IsAllowed<CanManageEvents>())
- {
- options.AddRows = true;
- options.EditRows = true;
- options.DeleteRows = true;
- }
- else
- {
- options.AddRows = false;
- options.EditRows = false;
- options.DeleteRows = false;
- }
- }
- #region Action Columns
- private FrameworkElement? Subscribed_ToolTip(DynamicActionColumn column, CoreRow? row)
- {
- if(row is null)
- {
- return column.TextToolTip("Are you subscribed to this event?");
- }
- else
- {
- return _subscribedSet.TryGetValue(row.Get<Event, Guid>(x => x.ID), out var type)
- ? (type == EventSubscriberType.Notification
- ? column.TextToolTip("You are subscribed to this event by notification.")
- : column.TextToolTip("You are subscribed to this event by email."))
- : null;
- }
- }
- private void BuildMenu(DynamicMenuColumn column, CoreRow? row)
- {
- if (row is null) return;
- var menu = column.GetMenu();
- var eventID = row.Get<Event, Guid>(x => x.ID);
- if (_subscribedSet.TryGetValue(eventID, out var type))
- {
- menu.AddItem("Unsubscribe", null, row, Unsubscribe);
- if(type == EventSubscriberType.Notification)
- {
- menu.AddItem("Subscribe by Email", null, (row, EventSubscriberType.Email), ChangeSubscription);
- }
- else
- {
- menu.AddItem("Subscribe by Notification", null, (row, EventSubscriberType.Notification), ChangeSubscription);
- }
- }
- else
- {
- menu.AddItem("Subscribe by Notification", null, (row, EventSubscriberType.Notification), Subscribe);
- menu.AddItem("Subscribe by Email", null, (row, EventSubscriberType.Email), Subscribe);
- }
- }
- private BitmapImage? Menu_GetImage(CoreRow? row)
- {
- if (row is null) return _notification;
- return _subscribedSet.TryGetValue(row.Get<Event, Guid>(x => x.ID), out var type)
- ? (type == EventSubscriberType.Notification ? _notification : _email)
- : null;
- }
- private void ChangeSubscription((CoreRow row, EventSubscriberType Notification) tuple)
- {
- Unsubscribe(tuple.row, false);
- Subscribe(tuple);
- }
- private void Subscribe((CoreRow row, EventSubscriberType type) tuple)
- {
- var ev = tuple.row.ToObject<Event>();
- var subscriber = new EventSubscriber();
- subscriber.Event.CopyFrom(ev);
- subscriber.Employee.ID = EmployeeID;
- subscriber.SubscriberType = tuple.type;
- Client.Save(subscriber, "");
- _subscribedSet.Add(ev.ID, subscriber.SubscriberType);
- Refresh(false, true);
- }
- private void Unsubscribe(CoreRow row)
- {
- Unsubscribe(row, true);
- }
- private void Unsubscribe(CoreRow row, bool refresh)
- {
- var eventID = row.Get<Event, Guid>(x => x.ID);
- var subscriber = Client.Query(
- new Filter<EventSubscriber>(x => x.Employee.ID).IsEqualTo(EmployeeID)
- .And(x => x.Event.ID).IsEqualTo(eventID),
- Columns.None<EventSubscriber>().Add(x => x.ID))
- .ToObjects<EventSubscriber>().FirstOrDefault();
- if(subscriber is not null)
- {
- Client.Delete(subscriber, "");
- }
- _subscribedSet.Remove(eventID);
- if (refresh)
- {
- Refresh(false, true);
- }
- }
- private bool Edit_Click(CoreRow? row)
- {
- if (row is null) return false;
- var ev = row.ToObject<Event>();
- IEventData? data = null;
- if(ev.Data is not null && ev.Data.Length != 0)
- {
- data = EventUtils.Deserialize(ev.Data);
- }
- var type = ev.EventType;
- if(EventEditor.Run(ref type, ref data))
- {
- ev.EventType = type;
- if(data is not null)
- {
- ev.Data = EventUtils.Serialize(data);
- }
- else
- {
- ev.Data = "";
- }
- SaveItem(ev);
- return true;
- }
- else
- {
- return false;
- }
- }
- #endregion
- private readonly Column<Event> EventTypeColumn = new(x => x.EventType);
- private readonly Column<Event> NotificationExpressionColumn = new(x => x.NotificationExpression);
- private IEventData? EventData;
- protected override void BeforeLoad(IDynamicEditorForm form, Event[] items)
- {
- base.BeforeLoad(form, items);
- form.ReadOnly = !Security.IsAllowed<CanManageEvents>();
- var ev = items.First();
- IEventData? data = null;
- if(ev.Data is not null && ev.Data.Length != 0)
- {
- data = EventUtils.Deserialize(ev.Data);
- }
- EventData = data;
- }
- protected override void CustomiseEditor(IDynamicEditorForm form, Event[] items, DynamicGridColumn column, BaseEditor editor)
- {
- base.CustomiseEditor(form, items, column, editor);
- if(EventTypeColumn.IsEqualTo(column.ColumnName) && editor is EnumLookupEditor enumEditor)
- {
- var ev = items.First();
- var editButton = new EditorButton(ev, "Edit Event", 100, (e, i) => EditEvent_Click(form, e, i), false);
- enumEditor.Buttons = [editButton];
- }
- else if(NotificationExpressionColumn.IsEqualTo(column.ColumnName) && editor is ExpressionEditor exprEditor)
- {
- exprEditor.OnGetVariables += ExprEditor_OnGetVariables;
- }
- }
- private IEnumerable<string> ExprEditor_OnGetVariables()
- {
- return EventData?.Event.DataModelDefinition().GetVariables().Select(x => x.Name) ?? [];
- }
- private void EditEvent_Click(IDynamicEditorForm form, object editor, object? item)
- {
- if (item is not Event ev) return;
- var type = ev.EventType;
- var data = EventData;
- if(EventEditor.Run(ref type, ref data))
- {
- EventData = data;
- ev.EventType = type;
- form.SetEditorValue(nameof(Event.EventType), type);
- if(data is not null)
- {
- ev.Data = EventUtils.Serialize(data);
- }
- else
- {
- ev.Data = "";
- }
- }
- else
- {
- // We have to 'cancel' by just re-deserialising.
- if(ev.Data is not null && ev.Data.Length != 0)
- {
- EventData = EventUtils.Deserialize(ev.Data);
- }
- }
- }
- protected override void Reload(Filters<Event> criteria, Columns<Event> columns, ref SortOrder<Event>? sort, CancellationToken token, Action<CoreTable?, Exception?> action)
- {
- if (!Security.IsAllowed<CanManageEvents>())
- {
- criteria.Add(new Filter<Event>(x => x.Visible).IsEqualTo(true));
- }
- base.Reload(criteria, columns, ref sort, token, (data, error) =>
- {
- if(data is not null)
- {
- var ids = data.ExtractValues<Event, Guid>(x => x.ID);
- _subscribedSet = Client.Query(
- new Filter<EventSubscriber>(x => x.Employee.ID).IsEqualTo(EmployeeID)
- .And(x => x.Event.ID).InList(ids),
- Columns.None<EventSubscriber>().Add(x => x.Event.ID).Add(x => x.SubscriberType))
- .ToObjects<EventSubscriber>().ToDictionary(x => x.Event.ID, x => x.SubscriberType);
- }
- action(data, error);
- });
- }
- }
|