JobDocumentSetPanel.xaml.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.ComponentModel;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Input;
  8. using System.Windows.Media;
  9. using System.Windows.Media.Imaging;
  10. using Comal.Classes;
  11. using InABox.Clients;
  12. using InABox.Core;
  13. using InABox.DynamicGrid;
  14. using InABox.WPF;
  15. using InABox.Wpf;
  16. using Inflector;
  17. using Color = System.Drawing.Color;
  18. using InABox.Configuration;
  19. namespace PRSDesktop
  20. {
  21. public class JobDocumentSetSettings : BaseObject, IGlobalConfigurationSettings
  22. {
  23. [Caption("Milestone Task",IncludePath = false)]
  24. public KanbanTypeLink DocumentMilestoneKanbanType { get; set; }
  25. }
  26. public partial class JobDocumentSetPanel : UserControl, IMasterDetailControl<Job>, IDataModelSource, IPanel<Job>
  27. {
  28. private enum Suppress
  29. {
  30. This
  31. }
  32. private JobDocumentSetSettings _settings = new();
  33. public Job? Master { get; set; }
  34. public JobDocumentSetPanel()
  35. {
  36. using (new EventSuppressor(Suppress.This))
  37. InitializeComponent();
  38. }
  39. public string SectionName => "Job Document Set";
  40. public DataModel DataModel(Selection selection)
  41. {
  42. var ids = Documents.Data != null ? Documents.Data.ExtractValues<JobDocumentSet, Guid>(x => x.ID).ToArray() : new Guid[] { };
  43. return new AutoDataModel<JobDocumentSet>(new Filter<JobDocumentSet>(x => x.ID).InList(ids));
  44. }
  45. public event DataModelUpdateEvent? OnUpdateDataModel;
  46. private static bool GetAreas(CoreTable areas, ComboBox target) //, RowDefinition row)
  47. {
  48. using (new EventSuppressor(Suppress.This))
  49. {
  50. Dictionary<Guid, String> result = new Dictionary<Guid, String>()
  51. {
  52. { Guid.Empty, "" } //$"All {type.ToString().Pluralize()}" }
  53. };
  54. areas.IntoDictionary<JobITP, Guid, String>(result, x => x.ID,
  55. (r) => $"{r.Get<JobITP, String>(c => c.Code)}: {r.Get<JobITP, String>(c => c.Description)}");
  56. // row.Height = result.Count > 1
  57. // ? new GridLength(1, GridUnitType.Auto)
  58. // : new GridLength(0, GridUnitType.Pixel);
  59. var value = target.SelectedValue;
  60. target.ItemsSource = result;
  61. target.SelectedValue = value;
  62. return result.Count > 1;
  63. }
  64. }
  65. private static bool GetTags(CoreTable tags, JobDocumentSetTagType type, ComboBox target) //, RowDefinition row)
  66. {
  67. using (new EventSuppressor(Suppress.This))
  68. {
  69. var result = new Dictionary<Guid, String>()
  70. {
  71. { Guid.Empty, "" }
  72. };
  73. foreach (var tag in tags.Rows.Where(x => x.Get<JobDocumentSetTag, JobDocumentSetTagType>(x => x.Type).Equals(type)))
  74. result[tag.Get<JobDocumentSetTag, Guid>(c => c.ID)] = tag.Get<JobDocumentSetTag, String>(c => c.Description);
  75. // row.Height = result.Count > 1
  76. // ? new GridLength(1, GridUnitType.Auto)
  77. // : new GridLength(0, GridUnitType.Pixel);
  78. var value = target.SelectedValue;
  79. target.ItemsSource = result;
  80. target.SelectedValue = value;
  81. return result.Count > 1;
  82. }
  83. }
  84. public void Setup()
  85. {
  86. _settings = new GlobalConfiguration<JobDocumentSetSettings>().Load();
  87. tasks.Settings = _settings;
  88. tasks.Refresh(true, false);
  89. }
  90. public void Shutdown(CancelEventArgs? cancel)
  91. {
  92. }
  93. public void Refresh()
  94. {
  95. LoadDocumentTags();
  96. Folders.Master = Master;
  97. Folders.Refresh();
  98. Documents.Master = Master;
  99. Documents.Refresh();
  100. }
  101. private void LoadDocumentTags()
  102. {
  103. // Global tags
  104. var tagFilter = new Filter<JobDocumentSetTag>(x => x.Job.ID).IsEqualTo(Guid.Empty);
  105. if(Master is not null && Master.ID != Guid.Empty)
  106. {
  107. tagFilter = tagFilter.Or(x => x.Job.ID).IsEqualTo(Master.ID);
  108. }
  109. var results = Client.QueryMultiple(
  110. new KeyedQueryDef<JobDocumentSetTag>(
  111. tagFilter,
  112. new Columns<JobDocumentSetTag>(x => x.ID)
  113. .Add(x => x.Type)
  114. .Add(x => x.Description),
  115. new SortOrder<JobDocumentSetTag>(x => x.Description)
  116. ),
  117. new KeyedQueryDef<JobITP>(
  118. new Filter<JobITP>(x => x.Job.ID).IsEqualTo(Master?.ID ?? Guid.Empty),
  119. new Columns<JobITP>(x => x.ID).Add(x => x.Code).Add(x => x.Description),
  120. new SortOrder<JobITP>(x => x.Code)));
  121. var tags = results.Get<JobDocumentSetTag>();
  122. /* Documents.DisciplineVisible = */
  123. GetTags(tags, JobDocumentSetTagType.Discipline, Discipline); //, DisciplineRow);
  124. /* Documents.TypeVisible = */
  125. GetTags(tags, JobDocumentSetTagType.Type, Type); //, TypeRow);
  126. /* Documents.CategoryVisible = */
  127. GetTags(tags, JobDocumentSetTagType.Category, Category); //, CategoryRow);
  128. /* Documents.AreaVisible = */
  129. GetAreas(results.Get<JobITP>(), Area); //, AreaRow);
  130. }
  131. public bool IsReady { get; set; }
  132. public void CreateToolbarButtons(IPanelHost host)
  133. {
  134. host.CreateSetupAction(new PanelAction() { Caption = "Job Settings", Image = PRSDesktop.Resources.specifications, OnExecute = JobSettingsClick });
  135. }
  136. private void JobSettingsClick(PanelAction obj)
  137. {
  138. if (DynamicGridUtils.Edit(_settings))
  139. new GlobalConfiguration<JobDocumentSetSettings>().Save(_settings);
  140. }
  141. public Dictionary<string, object[]> Selected()
  142. {
  143. return new Dictionary<string, object[]>();
  144. }
  145. public void Heartbeat(TimeSpan time)
  146. {
  147. }
  148. private Guid _folderid = Guid.Empty;
  149. private void Folders_OnOnSelectItem(CoreTreeNode node)
  150. {
  151. _folderid = node != null ? node.ID : Guid.Empty;
  152. LoadDocuments(_folderid);
  153. }
  154. private void LoadDocuments(Guid folderid)
  155. {
  156. List<Guid> folders = new List<Guid>();
  157. this.Folders.Nodes.GetChildren(folders, folderid);
  158. Documents.FolderIDs = folders.ToArray();
  159. Documents.Refresh();
  160. }
  161. private void DynamicSplitPanel_OnOnChanged(object sender, DynamicSplitPanelSettings e)
  162. {
  163. LoadDocuments(e.View == DynamicSplitPanelView.Detail ? Guid.Empty : _folderid);
  164. }
  165. private void Preview_OnSizeChanged(object sender, SizeChangedEventArgs e)
  166. {
  167. //throw new NotImplementedException();
  168. }
  169. private void Documents_OnMileStoneSelected(JobDocumentSetMileStoneBlock block)
  170. {
  171. tasks.JobID = Master?.ID ?? Guid.Empty;
  172. tasks.MileStoneID = block?.ID ?? Guid.Empty;
  173. tasks.Refresh(false, true);
  174. if (block != null && block.Attachments > 0)
  175. {
  176. var id = block.ID;
  177. var files = new Client<JobDocumentSetMileStoneFile>().Query(
  178. new Filter<JobDocumentSetMileStoneFile>(x => x.EntityLink.ID).IsEqualTo(block.ID),
  179. new Columns<JobDocumentSetMileStoneFile>(x => x.ID)
  180. .Add(x => x.DocumentLink.ID)
  181. .Add(x => x.DocumentLink.FileName)
  182. .Add(x => x.Thumbnail),
  183. new SortOrder<JobDocumentSetMileStoneFile>(x => x.DocumentLink.FileName)
  184. );
  185. preview.ItemsSource = files.Rows
  186. .Select(r =>
  187. new Tuple<Guid, String, BitmapImage, JobDocumentSetMileStoneFile>(
  188. r.Get<JobDocumentSetMileStoneFile, Guid>(c => c.ID),
  189. r.Get<JobDocumentSetMileStoneFile, String>(c => c.DocumentLink.FileName),
  190. r.Get<JobDocumentSetMileStoneFile, byte[]>(c => c.Thumbnail) != null
  191. ? String.IsNullOrWhiteSpace(block.Watermark)
  192. ? ImageUtils.LoadImage(r.Get<JobDocumentSetMileStoneFile, byte[]>(c => c.Thumbnail))
  193. : ImageUtils.LoadImage(r.Get<JobDocumentSetMileStoneFile, byte[]>(c => c.Thumbnail))
  194. .AsBitmap().WatermarkImage(block.Watermark, Color.LightSalmon)
  195. .AsBitmapImage()
  196. : ImageUtils.BitmapFromColor(Color.White, 256, 192, Color.Transparent)
  197. .WatermarkImage("No Preview\nAvailable", Color.LightGray).AsBitmapImage(),
  198. r.ToObject<JobDocumentSetMileStoneFile>()
  199. )
  200. ).ToList();
  201. }
  202. else
  203. preview.ItemsSource = new List<Tuple<Guid, String, BitmapImage, JobDocumentSetMileStoneFile>>();
  204. }
  205. private void Tag_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
  206. {
  207. Documents.DisciplineID = (Guid)(Discipline.SelectedValue ?? Guid.Empty);
  208. Documents.TypeID = (Guid)(Type.SelectedValue ?? Guid.Empty);
  209. Documents.CategoryID = (Guid)(Category.SelectedValue ?? Guid.Empty);
  210. Documents.AreaID = (Guid)(Area.SelectedValue ?? Guid.Empty);
  211. Documents.Refresh();
  212. }
  213. private void PDFDoubleClick(object sender, MouseButtonEventArgs e)
  214. {
  215. var image = (sender as ListViewItem).Content as Tuple<Guid, String, BitmapImage, JobDocumentSetMileStoneFile>;
  216. if (image != null)
  217. {
  218. var viewer = new DocumentEditor(new JobDocumentSetMileStoneFile[] { image.Item4 });
  219. viewer.ButtonsVisible = false;
  220. viewer.ShowDialog();
  221. }
  222. }
  223. private void Search_OnKeyUp(object sender, KeyEventArgs e)
  224. {
  225. if ((e.Key == Key.Enter) || (e.Key == Key.Return) || (e.Key == Key.Tab) || (e.Key == Key.OemBackTab))
  226. {
  227. Documents.SearchText = Search.Text;
  228. Documents.Refresh();
  229. }
  230. }
  231. private void EditDocumentTags(JobDocumentSetTagType tagtype)
  232. {
  233. var editor = new JobDocumentSetTagEditor()
  234. {
  235. TagType = tagtype,
  236. JobID = Master?.ID ?? Guid.Empty
  237. };
  238. editor.Refresh(true, true);
  239. var window = new DynamicContentDialog(editor, false);
  240. window.Title = $"{tagtype} Document Tags";
  241. window.ShowDialog();
  242. LoadDocumentTags();
  243. }
  244. private void DisciplineButton_OnClick(object sender, RoutedEventArgs e)
  245. {
  246. EditDocumentTags(JobDocumentSetTagType.Discipline);
  247. }
  248. private void TypeButton_OnClick(object sender, RoutedEventArgs e)
  249. {
  250. EditDocumentTags(JobDocumentSetTagType.Type);
  251. }
  252. private void CategoryButton_OnClick(object sender, RoutedEventArgs e)
  253. {
  254. EditDocumentTags(JobDocumentSetTagType.Category);
  255. }
  256. private void ShowPreview_OnClick(object sender, RoutedEventArgs e)
  257. {
  258. PreviewColumn.Width = new GridLength(260, GridUnitType.Pixel);
  259. ShowPreview.Visibility = Visibility.Collapsed;
  260. }
  261. private void HidePreview_OnClick(object sender, RoutedEventArgs e)
  262. {
  263. PreviewColumn.Width = new GridLength(0, GridUnitType.Pixel);
  264. ShowPreview.Visibility = Visibility.Visible;
  265. }
  266. private void Tasks_OnOnChanged(object sender, EventArgs args)
  267. {
  268. Documents.Refresh();
  269. }
  270. }
  271. }