NotificationsDock.xaml.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. using InABox.Core.Notifications;
  18. namespace PRSDesktop
  19. {
  20. public delegate void NotificationsChangedEvent(object sender);
  21. /// <summary>
  22. /// Interaction logic for NotificationsDock.xaml
  23. /// </summary>
  24. public partial class NotificationsDock : UserControl
  25. {
  26. public NotificationsDock()
  27. {
  28. InitializeComponent();
  29. NotificationsList.ItemsSource = Notifications;
  30. }
  31. private ObservableCollection<Notification> Notifications = new();
  32. public bool IsActive => Notifications.Any();
  33. public event NotificationsChangedEvent Changed;
  34. public void AddNotification(Notification notification)
  35. {
  36. Dispatcher.Invoke(() =>
  37. {
  38. if (!Notifications.Any(x => x.ID == notification.ID))
  39. {
  40. Notifications.Add(notification);
  41. }
  42. MessageHeader.Content = string.Format("{0} Notification{1}", Notifications.Count, Notifications.Count == 1 ? "" : "s");
  43. Changed?.Invoke(this);
  44. });
  45. }
  46. public void Refresh()
  47. {
  48. new Client<Notification>().Query(
  49. new Filter<Notification>(x => x.Employee.ID).IsEqualTo(App.EmployeeID).And(x => x.Closed)
  50. .IsEqualTo(DateTime.MinValue),
  51. new Columns<Notification>(
  52. x => x.ID,
  53. x => x.Title,
  54. //x => x.Description,
  55. x => x.Created,
  56. x => x.Sender.ID,
  57. x => x.Sender.Name,
  58. x => x.Job.ID,
  59. x => x.Job.Deleted,
  60. x => x.Job.JobNumber,
  61. //x => x.Kanban.ID,
  62. //x => x.Setout.ID,
  63. //x => x.Requisition.ID,
  64. //x => x.Delivery.ID,
  65. x => x.Employee.ID,
  66. x => x.EntityType,
  67. x => x.EntityID,
  68. x => x.Closed
  69. ),
  70. null, //new SortOrder<Notification>(x => x.Created, InABox.Core.SortDirection.Descending),
  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, PRSDesktop.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. new Filter<Notification>(x => x.ID).IsEqualTo(notification.ID),
  135. new Columns<Notification>(x => x.Description),
  136. null,
  137. (table, error) =>
  138. {
  139. var drow = table != null ? table.Rows.FirstOrDefault() : null;
  140. var desc = drow?.Get<Notification, string>(x => x.Description)?.Replace("background:NoColor;", "") ?? "";
  141. var ms = new MemoryStream(Encoding.ASCII.GetBytes(desc));
  142. Dispatcher.Invoke(() =>
  143. {
  144. notification.Description = desc;
  145. editor.Text = desc;
  146. });
  147. }
  148. );
  149. editor.Height = 200;
  150. ScrollViewer scroller = stack.Children.OfType<ScrollViewer>().FirstOrDefault();
  151. if (scroller == null)
  152. PreviewPhotos(notification, stack);
  153. }
  154. private void PreviewPhotos(Notification notification, StackPanel stack)
  155. {
  156. Task.Run(() =>
  157. {
  158. CoreTable table = new Client<NotificationDocument>().Query
  159. (
  160. new Filter<NotificationDocument>(x => x.EntityLink.ID).IsEqualTo(notification.ID),
  161. new Columns<NotificationDocument>(x => x.DocumentLink.ID, x => x.ID)
  162. );
  163. if (table.Rows.Any())
  164. {
  165. Dispatcher.Invoke(() =>
  166. {
  167. List<Image> images = new List<Image>();
  168. foreach (CoreRow row in table.Rows)
  169. {
  170. CoreTable table1 = new Client<Document>().Query
  171. (
  172. new Filter<Document>(x => x.ID).IsEqualTo(Guid.Parse(row.Values[0].ToString())),
  173. new Columns<Document>(x => x.FileName, x => x.Data, x => x.ID)
  174. );
  175. Image img = DataToImage((table1.Rows.FirstOrDefault().Values[1]) as byte[], table1.Rows.FirstOrDefault().Values[0].ToString());
  176. img.Tag = row.Values[1].ToString();
  177. images.Add(img);
  178. }
  179. ScrollViewer scroller = new ScrollViewer() { VerticalScrollBarVisibility = ScrollBarVisibility.Disabled, HorizontalScrollBarVisibility = ScrollBarVisibility.Visible };
  180. StackPanel photoPanel = new StackPanel();
  181. photoPanel.Height = 50;
  182. photoPanel.Orientation = Orientation.Horizontal;
  183. foreach (Image img in images)
  184. {
  185. photoPanel.Children.Add(img);
  186. }
  187. scroller.Content = photoPanel;
  188. stack.Children.Add(scroller);
  189. });
  190. }
  191. });
  192. }
  193. private void Notification_ReplyButton_Click(object sender, RoutedEventArgs e)
  194. {
  195. var notification = (sender as Button).Tag as Notification;
  196. if (NotificationUtils.ReplyOrForward(new[] { notification.ID }, "RE: ", true, false))
  197. Refresh();
  198. }
  199. private void Notification_ForwardButton_Click(object sender, RoutedEventArgs e)
  200. {
  201. var notification = (sender as Button).Tag as Notification;
  202. if (NotificationUtils.ReplyOrForward(new[] { notification.ID }, "FW: ", false, false))
  203. Refresh();
  204. }
  205. private void Notification_FormButton_Click(object sender, RoutedEventArgs e)
  206. {
  207. var notification = (sender as Button).Tag as Notification;
  208. NotificationUtils.ViewForm(new[] { notification.ID });
  209. }
  210. private void Notification_EntityButton_Click(object sender, RoutedEventArgs e)
  211. {
  212. var notification = (sender as Button).Tag as Notification;
  213. if (NotificationUtils.ViewEntity(new[] { notification.ID }))
  214. Refresh();
  215. }
  216. private void Notification_JobButton_Click(object sender, RoutedEventArgs e)
  217. {
  218. var notification = (sender as Button).Tag as Notification;
  219. if (notification.Job.IsValid())
  220. {
  221. NotificationUtils.ViewJob(new[] { notification.Job.ID });
  222. }
  223. else
  224. {
  225. if (NotificationUtils.AttachToJob(new[] { notification.ID }))
  226. Refresh();
  227. }
  228. }
  229. private void Notification_TaskButton_Click(object sender, RoutedEventArgs e)
  230. {
  231. var notification = (sender as Button).Tag as Notification;
  232. if (NotificationUtils.CreateTask(new[] { notification.ID }, App.EmployeeID))
  233. Refresh();
  234. }
  235. private void Notification_DeliveryButton_Click(object sender, RoutedEventArgs e)
  236. {
  237. var notification = (sender as Button).Tag as Notification;
  238. if (NotificationUtils.CreateDelivery(new[] { notification.ID }))
  239. Refresh();
  240. }
  241. private void Notification_RequisitionButton_Click(object sender, RoutedEventArgs e)
  242. {
  243. var notification = (sender as Button).Tag as Notification;
  244. if (NotificationUtils.CreateRequi(new[] { notification.ID }, App.EmployeeID))
  245. Refresh();
  246. }
  247. private void Notification_SetoutButton_Click(object sender, RoutedEventArgs e)
  248. {
  249. var notification = (sender as Button).Tag as Notification;
  250. if (NotificationUtils.CreateSetout(new[] { notification.ID }))
  251. Refresh();
  252. }
  253. private void Notification_DismissButton_Click(object sender, RoutedEventArgs e)
  254. {
  255. var notification = (sender as Button).Tag as Notification;
  256. if (NotificationUtils.Archive(new[] { notification.ID }))
  257. {
  258. var list = NotificationsList.ItemsSource as ObservableCollection<Notification>;
  259. if (list.Contains(notification))
  260. list.Remove(notification);
  261. MessageHeader.Content = string.Format("{0} Notification{1}", list.Count, list.Count == 1 ? "" : "s");
  262. Changed?.Invoke(this);
  263. }
  264. }
  265. private Image DataToImage(byte[] data, string filename)
  266. {
  267. Image img = new Image();
  268. img.Height = 50;
  269. img.Width = 50;
  270. img.Margin = new Thickness(5);
  271. img.MouseUp += Img_MouseUp;
  272. if (filename.EndsWith("png") || filename.EndsWith("jpg") || filename.EndsWith("jpeg") || filename.EndsWith("bmp"))
  273. {
  274. img.Source = ImageUtils.LoadImage(data);
  275. }
  276. else if (filename.EndsWith("pdf"))
  277. {
  278. img.Source = PRSDesktop.Resources.doc_pdf.AsBitmapImage();
  279. }
  280. return img;
  281. }
  282. private void Img_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
  283. {
  284. Image img = sender as Image;
  285. string str = img.Tag as string;
  286. Guid id = Guid.Parse(str);
  287. CoreTable table = new Client<NotificationDocument>().Query(new Filter<NotificationDocument>(x => x.ID).IsEqualTo(id),
  288. new Columns<NotificationDocument>(x => x.ID, x => x.DocumentLink.ID, x => x.DocumentLink.FileName));
  289. if (table.Rows.Any())
  290. {
  291. IEntityDocument doc = table.Rows.First().ToObject<NotificationDocument>();
  292. IEntityDocument[] docs = new IEntityDocument[] { doc };
  293. DocumentEditor editor = new DocumentEditor(docs);
  294. editor.Show();
  295. }
  296. }
  297. }
  298. }