NotificationsDock.xaml.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using Comal.Classes;
  10. using InABox.Clients;
  11. using InABox.Core;
  12. using InABox.DynamicGrid;
  13. using InABox.WPF;
  14. using Image = System.Windows.Controls.Image;
  15. using System.Threading.Tasks;
  16. using System.Collections.Generic;
  17. namespace PRSDesktop
  18. {
  19. public delegate void NotificationsChangedEvent(object sender);
  20. /// <summary>
  21. /// Interaction logic for NotificationsDock.xaml
  22. /// </summary>
  23. public partial class NotificationsDock : UserControl
  24. {
  25. public NotificationsDock()
  26. {
  27. InitializeComponent();
  28. NotificationsList.ItemsSource = Notifications;
  29. }
  30. private ObservableCollection<Notification> Notifications = new();
  31. public bool IsActive => Notifications.Any();
  32. public event NotificationsChangedEvent Changed;
  33. public void AddNotification(Notification notification)
  34. {
  35. Dispatcher.Invoke(() =>
  36. {
  37. if (!Notifications.Any(x => x.ID == notification.ID))
  38. {
  39. Notifications.Add(notification);
  40. }
  41. MessageHeader.Content = string.Format("{0} Notification{1}", Notifications.Count, Notifications.Count == 1 ? "" : "s");
  42. Changed?.Invoke(this);
  43. });
  44. }
  45. public void Refresh()
  46. {
  47. new Client<Notification>().Query(
  48. Filter<Notification>.Where(x => x.Employee.ID).IsEqualTo(App.EmployeeID).And(x => x.Closed)
  49. .IsEqualTo(DateTime.MinValue),
  50. Columns.None<Notification>().Add(
  51. x => x.ID,
  52. x => x.Title,
  53. //x => x.Description,
  54. x => x.Created,
  55. x => x.Sender.ID,
  56. x => x.Sender.Name,
  57. x => x.Job.ID,
  58. x => x.Job.Deleted,
  59. x => x.Job.JobNumber,
  60. //x => x.Kanban.ID,
  61. //x => x.Setout.ID,
  62. //x => x.Requisition.ID,
  63. //x => x.Delivery.ID,
  64. x => x.Employee.ID,
  65. x => x.EntityType,
  66. x => x.EntityID,
  67. x => x.Closed
  68. ),
  69. null, //new SortOrder<Notification>(x => x.Created, InABox.Core.SortDirection.Descending),
  70. CoreRange.All,
  71. (n, ex) =>
  72. {
  73. Dispatcher.Invoke(() =>
  74. {
  75. if (n != null)
  76. {
  77. MessageHeader.Content = string.Format("{0} Notification{1}", n.Rows.Count, n.Rows.Count == 1 ? "" : "s");
  78. Notifications.Clear();
  79. foreach(var notification in n.Rows.Select(r => r.ToObject<Notification>()))
  80. {
  81. Notifications.Add(notification);
  82. }
  83. Changed?.Invoke(this);
  84. }
  85. else
  86. {
  87. Changed?.Invoke(this);
  88. }
  89. });
  90. }
  91. );
  92. }
  93. private void Notification_Toolbar_Loaded(object sender, RoutedEventArgs e)
  94. {
  95. var toolBar = sender as ToolBar;
  96. var overflowGrid = toolBar.Template.FindName("OverflowGrid", toolBar) as FrameworkElement;
  97. if (overflowGrid != null)
  98. overflowGrid.Visibility = Visibility.Collapsed;
  99. var mainPanelBorder = toolBar.Template.FindName("MainPanelBorder", toolBar) as FrameworkElement;
  100. if (mainPanelBorder != null)
  101. mainPanelBorder.Margin = new Thickness();
  102. }
  103. private void LoadButton(ToolBar toolbar, Notification notification, int index, bool visible, Bitmap image, string tooltip)
  104. {
  105. var btn = toolbar.Items[index] as Button;
  106. btn.Tag = notification;
  107. btn.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
  108. var img = btn.Content as Image;
  109. img.Source = image.AsBitmapImage();
  110. btn.ToolTip = tooltip;
  111. }
  112. private void Expander_Expanded(object sender, RoutedEventArgs e)
  113. {
  114. var expander = sender as Expander;
  115. var notification = expander.Tag as Notification;
  116. var stack = (expander.Content as Border).Child as StackPanel;
  117. var isJob = notification.Job.IsValid();
  118. var isForm = NotificationUtils.IsDigitalForm(notification.EntityType);
  119. var entitytype = NotificationUtils.GetEntityType(notification.EntityType);
  120. var toolbar = stack.Children[0] as ToolBar;
  121. LoadButton(toolbar, notification, 0, true, InABox.Wpf.Resources.delete, "Dismiss");
  122. LoadButton(toolbar, notification, 1, true, PRSDesktop.Resources.reply, "Reply");
  123. LoadButton(toolbar, notification, 2, true, PRSDesktop.Resources.forward, "Forward");
  124. LoadButton(toolbar, notification, 3, isForm, PRSDesktop.Resources.checklist, "View Form");
  125. LoadButton(toolbar, notification, 4, entitytype != null, PRSDesktop.Resources.pencil,
  126. string.Format("View {0}", entitytype?.GetCaption()));
  127. LoadButton(toolbar, notification, 5, true, PRSDesktop.Resources.project, string.Format("{0} {1}", isJob ? "View" : "Attach To", "Job"));
  128. LoadButton(toolbar, notification, 6, entitytype != typeof(Kanban), PRSDesktop.Resources.kanban, "Create Task");
  129. LoadButton(toolbar, notification, 7, entitytype != typeof(Delivery), PRSDesktop.Resources.truck, "Create Delivery");
  130. LoadButton(toolbar, notification, 8, entitytype != typeof(Requisition), PRSDesktop.Resources.requisition, "Create Requisition");
  131. LoadButton(toolbar, notification, 9, entitytype != typeof(Setout), PRSDesktop.Resources.factory, "Create Setout");
  132. var editor = stack.Children[1] as ExtendedRichTextEditor;
  133. new Client<Notification>().Query(
  134. Filter<Notification>.Where(x => x.ID).IsEqualTo(notification.ID),
  135. Columns.None<Notification>().Add(x => x.Description),
  136. null,
  137. CoreRange.All,
  138. (table, error) =>
  139. {
  140. var drow = table != null ? table.Rows.FirstOrDefault() : null;
  141. var desc = drow?.Get<Notification, string>(x => x.Description)?.Replace("background:NoColor;", "") ?? "";
  142. var ms = new MemoryStream(Encoding.ASCII.GetBytes(desc));
  143. Dispatcher.Invoke(() =>
  144. {
  145. notification.Description = desc;
  146. editor.Text = desc;
  147. });
  148. }
  149. );
  150. editor.Height = 200;
  151. ScrollViewer scroller = stack.Children.OfType<ScrollViewer>().FirstOrDefault();
  152. if (scroller == null)
  153. PreviewPhotos(notification, stack);
  154. }
  155. private void PreviewPhotos(Notification notification, StackPanel stack)
  156. {
  157. Task.Run(() =>
  158. {
  159. CoreTable table = new Client<NotificationDocument>().Query
  160. (
  161. Filter<NotificationDocument>.Where(x => x.EntityLink.ID).IsEqualTo(notification.ID),
  162. Columns.None<NotificationDocument>().Add(x => x.DocumentLink.ID, x => x.ID)
  163. );
  164. if (table.Rows.Any())
  165. {
  166. Dispatcher.Invoke(() =>
  167. {
  168. List<Image> images = new List<Image>();
  169. foreach (CoreRow row in table.Rows)
  170. {
  171. CoreTable table1 = new Client<Document>().Query
  172. (
  173. Filter<Document>.Where(x => x.ID).IsEqualTo(Guid.Parse(row.Values[0].ToString())),
  174. Columns.None<Document>().Add(x => x.FileName, x => x.Data, x => x.ID)
  175. );
  176. Image img = DataToImage((table1.Rows.FirstOrDefault().Values[1]) as byte[], table1.Rows.FirstOrDefault().Values[0].ToString());
  177. img.Tag = row.Values[1].ToString();
  178. images.Add(img);
  179. }
  180. ScrollViewer scroller = new ScrollViewer() { VerticalScrollBarVisibility = ScrollBarVisibility.Disabled, HorizontalScrollBarVisibility = ScrollBarVisibility.Visible };
  181. StackPanel photoPanel = new StackPanel();
  182. photoPanel.Height = 50;
  183. photoPanel.Orientation = Orientation.Horizontal;
  184. foreach (Image img in images)
  185. {
  186. photoPanel.Children.Add(img);
  187. }
  188. scroller.Content = photoPanel;
  189. stack.Children.Add(scroller);
  190. });
  191. }
  192. });
  193. }
  194. private void Notification_ReplyButton_Click(object sender, RoutedEventArgs e)
  195. {
  196. var notification = (sender as Button).Tag as Notification;
  197. if (NotificationUtils.ReplyOrForward(new[] { notification.ID }, "RE: ", true, false))
  198. Refresh();
  199. }
  200. private void Notification_ForwardButton_Click(object sender, RoutedEventArgs e)
  201. {
  202. var notification = (sender as Button).Tag as Notification;
  203. if (NotificationUtils.ReplyOrForward(new[] { notification.ID }, "FW: ", false, false))
  204. Refresh();
  205. }
  206. private void Notification_FormButton_Click(object sender, RoutedEventArgs e)
  207. {
  208. var notification = (sender as Button).Tag as Notification;
  209. NotificationUtils.ViewForm(new[] { notification.ID });
  210. }
  211. private void Notification_EntityButton_Click(object sender, RoutedEventArgs e)
  212. {
  213. var notification = (sender as Button).Tag as Notification;
  214. if (NotificationUtils.ViewEntity(new[] { notification.ID }))
  215. Refresh();
  216. }
  217. private void Notification_JobButton_Click(object sender, RoutedEventArgs e)
  218. {
  219. var notification = (sender as Button).Tag as Notification;
  220. if (notification.Job.IsValid())
  221. {
  222. NotificationUtils.ViewJob(new[] { notification.Job.ID });
  223. }
  224. else
  225. {
  226. if (NotificationUtils.AttachToJob(new[] { notification.ID }))
  227. Refresh();
  228. }
  229. }
  230. private void Notification_TaskButton_Click(object sender, RoutedEventArgs e)
  231. {
  232. var notification = (sender as Button).Tag as Notification;
  233. if (NotificationUtils.CreateTask(new[] { notification.ID }, App.EmployeeID))
  234. Refresh();
  235. }
  236. private void Notification_DeliveryButton_Click(object sender, RoutedEventArgs e)
  237. {
  238. var notification = (sender as Button).Tag as Notification;
  239. if (NotificationUtils.CreateDelivery(new[] { notification.ID }))
  240. Refresh();
  241. }
  242. private void Notification_RequisitionButton_Click(object sender, RoutedEventArgs e)
  243. {
  244. var notification = (sender as Button).Tag as Notification;
  245. if (NotificationUtils.CreateRequi(new[] { notification.ID }, App.EmployeeID))
  246. Refresh();
  247. }
  248. private void Notification_SetoutButton_Click(object sender, RoutedEventArgs e)
  249. {
  250. var notification = (sender as Button).Tag as Notification;
  251. if (NotificationUtils.CreateSetout(new[] { notification.ID }))
  252. Refresh();
  253. }
  254. private void Notification_DismissButton_Click(object sender, RoutedEventArgs e)
  255. {
  256. var notification = (sender as Button).Tag as Notification;
  257. if (NotificationUtils.Archive(new[] { notification.ID }))
  258. {
  259. var list = NotificationsList.ItemsSource as ObservableCollection<Notification>;
  260. if (list.Contains(notification))
  261. list.Remove(notification);
  262. MessageHeader.Content = string.Format("{0} Notification{1}", list.Count, list.Count == 1 ? "" : "s");
  263. Changed?.Invoke(this);
  264. }
  265. }
  266. private Image DataToImage(byte[] data, string filename)
  267. {
  268. Image img = new Image();
  269. img.Height = 50;
  270. img.Width = 50;
  271. img.Margin = new Thickness(5);
  272. img.MouseUp += Img_MouseUp;
  273. if (filename.EndsWith("png") || filename.EndsWith("jpg") || filename.EndsWith("jpeg") || filename.EndsWith("bmp"))
  274. {
  275. img.Source = ImageUtils.LoadImage(data);
  276. }
  277. else if (filename.EndsWith("pdf"))
  278. {
  279. img.Source = PRSDesktop.Resources.doc_pdf.AsBitmapImage();
  280. }
  281. return img;
  282. }
  283. private void Img_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
  284. {
  285. Image img = sender as Image;
  286. string str = img.Tag as string;
  287. Guid id = Guid.Parse(str);
  288. CoreTable table = new Client<NotificationDocument>().Query(Filter<NotificationDocument>.Where(x => x.ID).IsEqualTo(id),
  289. Columns.None<NotificationDocument>().Add(x => x.ID, x => x.DocumentLink.ID, x => x.DocumentLink.FileName));
  290. if (table.Rows.Any())
  291. {
  292. IEntityDocument doc = table.Rows.First().ToObject<NotificationDocument>();
  293. IEntityDocument[] docs = new IEntityDocument[] { doc };
  294. DocumentEditor editor = new DocumentEditor(docs);
  295. editor.Show();
  296. }
  297. }
  298. }
  299. }