NotificationsDock.xaml.cs 14 KB

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