NotificationPanel.xaml.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Media.Imaging;
  9. using Comal.Classes;
  10. using InABox.Clients;
  11. using InABox.Core;
  12. using InABox.DynamicGrid;
  13. using InABox.WPF;
  14. using InABox.Wpf;
  15. using System.ComponentModel;
  16. using sun.net.www;
  17. using Syncfusion.Windows.Controls.RichTextBoxAdv;
  18. using static ICSharpCode.AvalonEdit.Document.TextDocumentWeakEventManager;
  19. using SelectionChangedEventArgs = System.Windows.Controls.SelectionChangedEventArgs;
  20. using PRS.Shared;
  21. namespace PRSDesktop;
  22. /// <summary>
  23. /// Interaction logic for NotificationPanel.xaml
  24. /// </summary>
  25. public partial class NotificationPanel : UserControl, IPanel<Notification>
  26. {
  27. private readonly Button Archive;
  28. private readonly Button AttachToJob;
  29. private readonly Button CreateDelivery;
  30. private readonly Button CreateRequi;
  31. private readonly Button CreateSetout;
  32. private readonly Button CreateTask;
  33. private readonly List<Tuple<string, BitmapImage>> folders = new()
  34. {
  35. new("Inbox", PRSDesktop.Resources.download.AsBitmapImage()),
  36. new("Sent", PRSDesktop.Resources.upload.AsBitmapImage()),
  37. new("Archive", PRSDesktop.Resources.box.AsBitmapImage())
  38. };
  39. private readonly Button Forward;
  40. private readonly Employee me = new Client<Employee>().Load(new Filter<Employee>(x => x.UserLink.ID).IsEqualTo(ClientFactory.UserGuid))
  41. .FirstOrDefault();
  42. private readonly DynamicDataGrid<Notification> Notifications;
  43. private readonly Button Reopen;
  44. //Button WriteNew = null;
  45. private readonly Button Reply;
  46. private readonly Button ViewEntity;
  47. private readonly Button ViewForm;
  48. private readonly Button ViewJob;
  49. public NotificationPanel()
  50. {
  51. InitializeComponent();
  52. Notifications = new DynamicDataGrid<Notification>();
  53. Notifications.HiddenColumns.Add(x => x.Sender.ID);
  54. Notifications.HiddenColumns.Add(x => x.Employee.ID);
  55. Notifications.HiddenColumns.Add(x => x.Job.ID);
  56. Notifications.HiddenColumns.Add(x => x.EntityType);
  57. Notifications.HiddenColumns.Add(x => x.EntityID);
  58. //Notifications.HiddenColumns.Add(x => x.Kanban.ID);
  59. //Notifications.HiddenColumns.Add(x => x.Setout.ID);
  60. //Notifications.HiddenColumns.Add(x => x.Requisition.ID);
  61. //Notifications.HiddenColumns.Add(x => x.Delivery.ID);
  62. //Notifications.HiddenColumns.Add(x => x.LeaveRequestLink.ID);
  63. Notifications.HiddenColumns.Add(x => x.Closed);
  64. Notifications.Reconfigure(options =>
  65. {
  66. options.RecordCount = true;
  67. options.FilterRows = true;
  68. options.SelectColumns = true;
  69. options.MultiSelect = true;
  70. });
  71. Notifications.SetValue(Grid.RowProperty, 0);
  72. Notifications.SetValue(Grid.ColumnProperty, 1);
  73. Notifications.Margin = new Thickness(0);
  74. Notifications.OnReload += Notifications_OnReload;
  75. Notifications.OnSelectItem += Notifications_OnSelectItem;
  76. Notifications.OnValidate += Notifications_OnValidate;
  77. Notifications.OnCreateItem += Notifications_OnCreateItem;
  78. //WriteNew = CreateButton("Write New", null, WriteNewClick);
  79. //WriteNew.Visibility = Visibility.Visible;
  80. //WriteNew.Margin = new Thickness(WriteNew.Margin.Left, WriteNew.Margin.Top, 10.0F, WriteNew.Margin.Bottom);
  81. Reply = CreateButton("Reply", null, ReplyClick);
  82. Forward = CreateButton("Forward", null, ForwardClick);
  83. ViewForm = CreateButton("View Form", null, ViewFormClick);
  84. ViewEntity = CreateButton("View Item", null, ViewEntityClick);
  85. AttachToJob = CreateButton("Attach To Job", null, AttachToJobClick);
  86. ViewJob = CreateButton("View Job", null, ViewJobClick);
  87. CreateTask = CreateButton("Create Task", null, CreateTaskClick);
  88. CreateSetout = CreateButton("Create Setout", null, CreateSetoutClick);
  89. CreateRequi = CreateButton("Create Requi", null, CreateRequiClick);
  90. CreateDelivery = CreateButton("Create Delivery", null, CreateDeliveryClick);
  91. Archive = CreateButton("Archive", null, ArchiveClick);
  92. Archive.Margin = new Thickness(10.0F, Archive.Margin.Top, Archive.Margin.Right, Archive.Margin.Bottom);
  93. Reopen = CreateButton("Reopen", null, ReopenClick);
  94. Reopen.Margin = new Thickness(10.0F, Reopen.Margin.Top, Reopen.Margin.Right, Reopen.Margin.Bottom);
  95. Layout.Children.Add(Notifications);
  96. Folders.ItemsSource = folders;
  97. }
  98. private void Notifications_OnCreateItem(object sender, object item)
  99. {
  100. if (item is not Notification notification)
  101. return;
  102. notification.Sender.ID = me.ID;
  103. }
  104. private void Notifications_OnValidate(object sender, Notification[] items, List<string> errors)
  105. {
  106. foreach(var item in items)
  107. {
  108. if(!item.Sender.IsValid())
  109. {
  110. errors.Add("[Sender] may not be blank!");
  111. }
  112. if(!item.Employee.IsValid())
  113. {
  114. errors.Add("[Employee] may not be blank!");
  115. }
  116. }
  117. }
  118. public bool IsReady { get; set; }
  119. public event DataModelUpdateEvent? OnUpdateDataModel;
  120. private Button CreateButton(string caption, BitmapImage? umage, DynamicGridButtonClickEvent action)
  121. {
  122. var result = Notifications.AddButton(caption, umage, action);
  123. result.Width = 100.0F;
  124. result.Visibility = Visibility.Collapsed;
  125. return result;
  126. }
  127. private void Notifications_OnSelectItem(object sender, DynamicGridSelectionEventArgs e)
  128. {
  129. var singlerow = e.Rows?.Length == 1;
  130. //WriteNew.Visibility = (Folders.SelectedIndex == 0) ? Visibility.Visible : Visibility.Collapsed;
  131. var row = e.Rows?.FirstOrDefault();
  132. if (row != null)
  133. {
  134. var hasjob = row.IsEntityLinkValid<Notification, JobLink>(x => x.Job);
  135. var entitytype = row.Get<Notification, string>(x => x.EntityType);
  136. NotificationUtils.MakeVisible(Reply, 0, 5, singlerow, Folders.SelectedIndex == 0 || Folders.SelectedIndex == 2);
  137. NotificationUtils.MakeVisible(Forward, 5, 10, singlerow);
  138. NotificationUtils.MakeVisible(ViewForm, 0, 5, singlerow, NotificationUtils.IsDigitalForm(entitytype));
  139. NotificationUtils.MakeVisible(ViewEntity, 0, 10, singlerow, !string.IsNullOrWhiteSpace(entitytype));
  140. ViewEntity.Content = string.Format("View {0}", NotificationUtils.GetEntityType(entitytype)?.GetCaption());
  141. NotificationUtils.MakeVisible(AttachToJob, 0, 10, singlerow, !hasjob);
  142. NotificationUtils.MakeVisible(ViewJob, 0, 10, singlerow, hasjob, !string.Equals(entitytype, typeof(Job).EntityName()));
  143. var create = NotificationUtils.MakeVisible(CreateTask, 0, 5, singlerow, !string.Equals(entitytype, typeof(Kanban).EntityName()));
  144. create = NotificationUtils.MakeVisible(CreateSetout, 0, 5, singlerow, hasjob, !string.Equals(entitytype, typeof(Setout).EntityName())) ||
  145. create;
  146. create =
  147. NotificationUtils.MakeVisible(CreateRequi, 0, 5, singlerow, hasjob, !string.Equals(entitytype, typeof(Requisition).EntityName())) ||
  148. create;
  149. create = NotificationUtils.MakeVisible(CreateDelivery, 0, 5, singlerow, !string.Equals(entitytype, typeof(Delivery).EntityName())) ||
  150. create;
  151. NotificationUtils.MakeVisible(Archive, create ? 10 : 0, 5, Folders.SelectedIndex == 0);
  152. NotificationUtils.MakeVisible(Reopen, create ? 10 : 0, 5, Folders.SelectedIndex == 2);
  153. new Client<Notification>().Query(
  154. new Filter<Notification>(x => x.ID).IsEqualTo(row.Get<Notification, Guid>(x => x.ID)),
  155. Columns.None<Notification>().Add(x => x.Description),
  156. null,
  157. CoreRange.All,
  158. (table, error) =>
  159. {
  160. var drow = table?.Rows.FirstOrDefault();
  161. var desc = drow?.Get<Notification, string>(x => x.Description)?.Replace("background:NoColor;", "") ?? "";
  162. var ms = new MemoryStream(Encoding.ASCII.GetBytes(desc));
  163. Dispatcher.Invoke(() =>
  164. {
  165. Editor.Load(ms, FormatType.Html);
  166. //cursor.Dispose();
  167. });
  168. }
  169. );
  170. }
  171. else
  172. {
  173. NotificationUtils.MakeVisible(Reply, 0, 0, false);
  174. NotificationUtils.MakeVisible(Forward, 0, 0, false);
  175. NotificationUtils.MakeVisible(ViewForm, 0, 0, false);
  176. NotificationUtils.MakeVisible(ViewEntity, 0, 0, false);
  177. NotificationUtils.MakeVisible(AttachToJob, 0, 0, false);
  178. NotificationUtils.MakeVisible(ViewJob, 0, 0, false);
  179. NotificationUtils.MakeVisible(CreateTask, 0, 0, false);
  180. NotificationUtils.MakeVisible(CreateSetout, 0, 0, false);
  181. NotificationUtils.MakeVisible(CreateRequi, 0, 0, false);
  182. NotificationUtils.MakeVisible(CreateDelivery, 0, 0, false);
  183. NotificationUtils.MakeVisible(Archive, 0, 0, false);
  184. NotificationUtils.MakeVisible(Reopen, 0, 0, false);
  185. var ms = new MemoryStream(Encoding.ASCII.GetBytes(""));
  186. Editor.Load(ms, FormatType.Html);
  187. }
  188. }
  189. public void AddNotification(Notification notification)
  190. {
  191. Dispatcher.Invoke(() =>
  192. {
  193. if (IsInbox)
  194. {
  195. //Notifications.AddRow(notification);
  196. Notifications.Refresh(false, true);
  197. }
  198. });
  199. }
  200. private bool IsInbox => Folders.SelectedIndex == 0;
  201. private bool IsOutbox => Folders.SelectedIndex == 1;
  202. private bool IsArchive => Folders.SelectedIndex == 2;
  203. private void Notifications_OnReload(object sender, Filters<Notification> criteria, Columns<Notification> columns,
  204. ref SortOrder<Notification>? sortby)
  205. {
  206. var filter = new Filter<Notification>(x => x.ID).IsEqualTo(Guid.Empty);
  207. if (me != null)
  208. {
  209. if (IsInbox)
  210. filter = new Filter<Notification>(x => x.Employee.ID).IsEqualTo(me.ID).And(x => x.Closed).IsEqualTo(DateTime.MinValue);
  211. else if (IsOutbox)
  212. filter = new Filter<Notification>(x => x.Sender.ID).IsEqualTo(me.ID);
  213. else if (IsArchive)
  214. filter = new Filter<Notification>(x => x.Employee.ID).IsEqualTo(me.ID).And(x => x.Closed).IsNotEqualTo(DateTime.MinValue);
  215. }
  216. criteria.Add(filter);
  217. sortby = new SortOrder<Notification>(x => x.Created, SortDirection.Descending);
  218. }
  219. private void Folders_SelectionChanged(object sender, SelectionChangedEventArgs e)
  220. {
  221. if (IsReady)
  222. using (new WaitCursor())
  223. {
  224. Notifications.ColumnsTag = folders[Folders.SelectedIndex].Item1;
  225. Notifications.Refresh(true, true);
  226. }
  227. }
  228. #region IPanel<T> stuff
  229. public void CreateToolbarButtons(IPanelHost host)
  230. {
  231. // host.CreatePanelAction(new PanelAction() { Caption = "Send Notification", Image = PRSDesktop.Resources.email, OnExecute = SendNotificationClick });
  232. host.CreateSetupAction(
  233. Security.IsAllowed<CanManageEvents>() ? "Events" : "Event Subscriptions",
  234. Security.IsAllowed<CanManageEvents>() ? PRSDesktop.Resources.edit : PRSDesktop.Resources.email, action =>
  235. {
  236. var list = new MasterList(typeof(Event), dynamicGrid: new EventGrid
  237. {
  238. EmployeeID = App.EmployeeID
  239. });
  240. list.ShowDialog();
  241. });
  242. }
  243. public void Setup()
  244. {
  245. Folders.SelectedIndex = 0;
  246. Notifications.ColumnsTag = folders[Folders.SelectedIndex].Item1;
  247. Notifications.Refresh(true, false);
  248. }
  249. public void Shutdown(CancelEventArgs? cancel)
  250. {
  251. }
  252. public void Refresh()
  253. {
  254. Notifications.Refresh(false, true);
  255. }
  256. public string SectionName => "Notifications";
  257. public DataModel DataModel(Selection selection)
  258. {
  259. var ids = Notifications.ExtractValues(c => c.ID, selection).ToArray();
  260. return new BaseDataModel<Notification>(new Filter<Notification>(x => x.ID).InList(ids));
  261. }
  262. public Dictionary<string, object[]> Selected()
  263. {
  264. return new Dictionary<string, object[]>();
  265. }
  266. #endregion
  267. #region Actions
  268. private Guid[] SelectedIDs => Notifications.ExtractValues(x => x.ID, Selection.Selected).ToArray();
  269. private bool ViewFormClick(Button sender, CoreRow[] rows)
  270. {
  271. return NotificationUtils.ViewForm(SelectedIDs);
  272. }
  273. private bool ViewEntityClick(Button sender, CoreRow[] rows)
  274. {
  275. return NotificationUtils.ViewEntity(SelectedIDs);
  276. }
  277. private bool WriteNewClick(Button sender, CoreRow[] rows)
  278. {
  279. var form = new NotificationForm();
  280. return form.ShowDialog() == true;
  281. }
  282. private bool ReplyClick(Button sender, CoreRow[] rows)
  283. {
  284. return NotificationUtils.ReplyOrForward(SelectedIDs, "RE:", true, Folders.SelectedIndex == 1);
  285. }
  286. private bool ForwardClick(Button sender, CoreRow[] rows)
  287. {
  288. return NotificationUtils.ReplyOrForward(SelectedIDs, "FW:", false, Folders.SelectedIndex == 1);
  289. }
  290. private bool CreateTaskClick(Button sender, CoreRow[] rows)
  291. {
  292. return NotificationUtils.CreateTask(SelectedIDs, me.ID);
  293. }
  294. private bool AttachToJobClick(Button sender, CoreRow[] rows)
  295. {
  296. return NotificationUtils.AttachToJob(SelectedIDs);
  297. }
  298. private bool ViewJobClick(Button sender, CoreRow[] rows)
  299. {
  300. return NotificationUtils.ViewJob(SelectedIDs);
  301. }
  302. private bool CreateSetoutClick(Button sender, CoreRow[] rows)
  303. {
  304. return NotificationUtils.CreateSetout(SelectedIDs);
  305. }
  306. private bool CreateRequiClick(Button sender, CoreRow[] rows)
  307. {
  308. return NotificationUtils.CreateRequi(SelectedIDs, me.ID);
  309. }
  310. private bool CreateDeliveryClick(Button sender, CoreRow[] rows)
  311. {
  312. return NotificationUtils.CreateDelivery(SelectedIDs);
  313. }
  314. private bool ArchiveClick(Button sender, CoreRow[] rows)
  315. {
  316. return NotificationUtils.Archive(SelectedIDs);
  317. }
  318. private bool ReopenClick(Button sender, CoreRow[] rows)
  319. {
  320. return NotificationUtils.Reopen(SelectedIDs);
  321. }
  322. public void Heartbeat(TimeSpan time)
  323. {
  324. }
  325. #endregion
  326. }