EventGrid.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using InABox.DynamicGrid;
  5. using InABox.WPF;
  6. using PRS.Shared.Events;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows;
  14. using System.Windows.Media.Imaging;
  15. namespace PRS.Shared;
  16. public class EventGrid : DynamicDataGrid<Event>
  17. {
  18. private readonly BitmapImage _tick = InABox.Wpf.Resources.Bullet_Tick.AsBitmapImage();
  19. private HashSet<Guid> _subscribedSet = new();
  20. public Guid EmployeeID { get; set; }
  21. protected override void Init()
  22. {
  23. base.Init();
  24. HiddenColumns.Add(x => x.Data);
  25. ActionColumns.Add(new DynamicImageColumn(Subscribed_Image) { ToolTip = Subscribed_ToolTip });
  26. ActionColumns.Add(new DynamicMenuColumn(BuildMenu));
  27. }
  28. #region Action Columns
  29. private FrameworkElement? Subscribed_ToolTip(DynamicActionColumn column, CoreRow? row)
  30. {
  31. if(row is null)
  32. {
  33. return column.TextToolTip("Are you subscribed to this event?");
  34. }
  35. else
  36. {
  37. return _subscribedSet.Contains(row.Get<Event, Guid>(x => x.ID))
  38. ? column.TextToolTip("You are subscribed to this event.")
  39. : null;
  40. }
  41. }
  42. private BitmapImage? Subscribed_Image(CoreRow? row)
  43. {
  44. if(row is null)
  45. {
  46. return _tick;
  47. }
  48. else
  49. {
  50. return _subscribedSet.Contains(row.Get<Event, Guid>(x => x.ID)) ? _tick : null;
  51. }
  52. }
  53. private void BuildMenu(DynamicMenuColumn column, CoreRow? row)
  54. {
  55. if (row is null) return;
  56. var eventID = row.Get<Event, Guid>(x => x.ID);
  57. var menu = column.GetMenu();
  58. if(_subscribedSet.Contains(eventID))
  59. {
  60. menu.AddItem("Unsubscribe from event", null, row, Unsubscribe_Click);
  61. }
  62. else
  63. {
  64. menu.AddItem("Subscribe to event", null, row, Subscribe_Click);
  65. }
  66. }
  67. private void Unsubscribe_Click(CoreRow row)
  68. {
  69. var eventID = row.Get<Event, Guid>(x => x.ID);
  70. var subscriber = Client.Query(
  71. new Filter<EventSubscriber>(x => x.Employee.ID).IsEqualTo(EmployeeID)
  72. .And(x => x.Event.ID).IsEqualTo(eventID),
  73. Columns.None<EventSubscriber>().Add(x => x.ID))
  74. .ToObjects<EventSubscriber>().FirstOrDefault();
  75. if(subscriber is not null)
  76. {
  77. Client.Delete(subscriber, "");
  78. }
  79. _subscribedSet.Remove(eventID);
  80. InvalidateRow(row);
  81. }
  82. private void Subscribe_Click(CoreRow row)
  83. {
  84. var ev = row.ToObject<Event>();
  85. var subscriber = new EventSubscriber();
  86. subscriber.Event.CopyFrom(ev);
  87. subscriber.Employee.ID = EmployeeID;
  88. Client.Save(subscriber, "");
  89. _subscribedSet.Add(ev.ID);
  90. InvalidateRow(row);
  91. }
  92. #endregion
  93. private readonly Column<Event> EventTypeColumn = new(x => x.EventType);
  94. protected override void CustomiseEditor(Event[] items, DynamicGridColumn column, BaseEditor editor)
  95. {
  96. base.CustomiseEditor(items, column, editor);
  97. if(EventTypeColumn.IsEqualTo(column.ColumnName) && editor is EnumLookupEditor enumEditor)
  98. {
  99. var ev = items.First();
  100. var editButton = new EditorButton(ev, "Edit Event", 100, EditEvent_Click, false);
  101. enumEditor.Buttons = [editButton];
  102. }
  103. }
  104. private void EditEvent_Click(object editor, object? item)
  105. {
  106. if (item is not Event ev) return;
  107. var type = ev.EventType;
  108. IEventData? data = null;
  109. if(ev.Data is not null && ev.Data.Length != 0)
  110. {
  111. using var stream = new MemoryStream(ev.Data);
  112. var reader = new CoreBinaryReader(stream, BinarySerializationSettings.Latest);
  113. data = EventUtils.Deserialize(reader);
  114. }
  115. if(EventEditor.Run(ref type, ref data))
  116. {
  117. ev.EventType = type;
  118. if(data is not null)
  119. {
  120. using var stream = new MemoryStream();
  121. EventUtils.Serialize(data, new CoreBinaryWriter(stream, BinarySerializationSettings.Latest));
  122. ev.Data = stream.ToArray();
  123. }
  124. else
  125. {
  126. ev.Data = [];
  127. }
  128. }
  129. }
  130. protected override void Reload(Filters<Event> criteria, Columns<Event> columns, ref SortOrder<Event>? sort, CancellationToken token, Action<CoreTable?, Exception?> action)
  131. {
  132. base.Reload(criteria, columns, ref sort, token, (data, error) =>
  133. {
  134. if(data is not null)
  135. {
  136. var ids = data.ExtractValues<Event, Guid>(x => x.ID);
  137. _subscribedSet = Client.Query(
  138. new Filter<EventSubscriber>(x => x.Employee.ID).IsEqualTo(EmployeeID)
  139. .And(x => x.Event.ID).InList(ids),
  140. Columns.None<EventSubscriber>().Add(x => x.Event.ID))
  141. .ToObjects<EventSubscriber>().Select(x => x.Event.ID).ToHashSet();
  142. }
  143. action(data, error);
  144. });
  145. }
  146. }