JobDocuments.xaml.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Collections.ObjectModel;
  7. using System.ComponentModel;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Threading.Tasks;
  11. using Xamarin.Essentials;
  12. using Xamarin.Forms;
  13. using Xamarin.Forms.Xaml;
  14. using PRSSecurity = InABox.Core.Security;
  15. namespace comal.timesheets
  16. {
  17. public delegate void OnFolderListChanged();
  18. [XamlCompilation(XamlCompilationOptions.Compile)]
  19. public partial class JobDocuments : SitePage
  20. {
  21. #region Fields and Constructor / Navigation
  22. ObservableCollection<FolderViewItem> folderList = new ObservableCollection<FolderViewItem>();
  23. ObservableCollection<FolderViewItem> displayList = new ObservableCollection<FolderViewItem>();
  24. DeviceIdiom idiom;
  25. bool foldersLoaded = false;
  26. bool filesLoaded = false;
  27. bool specificQueryLoading = false;
  28. Dictionary<JobDocFilterType, string> filters = new Dictionary<JobDocFilterType, string>();
  29. Guid jobID = Guid.Empty;
  30. List<Guid> loadedFolders = new List<Guid>();
  31. List<MileStoneShell> mileStoneShells = new List<MileStoneShell>();
  32. List<JobDocSetFileShell> fullListShells = new List<JobDocSetFileShell>();
  33. List<JobDocSetFileShell> filteredShells = new List<JobDocSetFileShell>();
  34. List<JobDocSetFileShell> searchList = new List<JobDocSetFileShell>();
  35. List<MileStoneShell> specificQueryMileStones = new List<MileStoneShell>();
  36. List<JobDocSetFileShell> specificQueryFileShells = new List<JobDocSetFileShell>();
  37. List<JobDocSetFileShell> currentQueryFileShells = new List<JobDocSetFileShell>();
  38. public JobDocuments()
  39. {
  40. InitializeComponent();
  41. }
  42. protected override void JobLoaded()
  43. {
  44. //Title = Job.Item.DisplayName;
  45. treeView.QueryNodeSize += TreeView_QueryNodeSize;
  46. idiom = DeviceInfo.Idiom;
  47. if (Device.RuntimePlatform.Equals(Device.iOS))
  48. {
  49. expandImg.HeightRequest = 50;
  50. expandImg.WidthRequest = 50;
  51. collapseImg.HeightRequest = 50;
  52. collapseImg.WidthRequest = 50;
  53. }
  54. jobID = Job.Item.ID;
  55. LoadFiles(new Filter<JobDocumentSetMileStone>(x => x.DocumentSet.Job.ID).IsEqualTo(jobID));
  56. LoadFolders(jobID);
  57. }
  58. void ExitBtn_Clicked(object sender, EventArgs e)
  59. {
  60. Navigation.PopAsync();
  61. }
  62. private void FilterButton_Tapped(object sender, EventArgs e)
  63. {
  64. var page = new JobDocsFilterPage(jobID, filters);
  65. page.OnJobDocFiltersPicked += Page_OnJobDocFiltersPicked;
  66. Navigation.PushAsync(page);
  67. }
  68. private void Page_OnJobDocFiltersPicked(Dictionary<JobDocFilterType, string> newfilters)
  69. {
  70. filterLayout.Children.Clear();
  71. filteredShells.Clear();
  72. filters.Clear();
  73. filters = new Dictionary<JobDocFilterType, string>(newfilters);
  74. AddFilters();
  75. DisplayFolderContents();
  76. }
  77. private void AddFilters()
  78. {
  79. foreach (var filter in filters)
  80. {
  81. JobDocFilterItem item = new JobDocFilterItem();
  82. item.Init(filter.Key, filter.Value);
  83. item.OnJobDocFilterClosed += ((filter, type) =>
  84. {
  85. filters.Remove(type);
  86. Page_OnJobDocFiltersPicked(new Dictionary<JobDocFilterType, string>(filters));
  87. });
  88. filterLayout.Children.Add(item);
  89. FilterList(filter.Key, filter.Value);
  90. }
  91. }
  92. private void FilterList(JobDocFilterType type, string text)
  93. {
  94. if (type == JobDocFilterType.Discipline)
  95. {
  96. var list = fullListShells.Where(x => x.DocSetDiscipline.Equals(text));
  97. foreach (var v in list)
  98. CheckDuplicateAndAdd(v);
  99. }
  100. else if (type == JobDocFilterType.Type)
  101. {
  102. var list = fullListShells.Where(x => x.DocSetType.Equals(text));
  103. foreach (var v in list)
  104. CheckDuplicateAndAdd(v);
  105. }
  106. else if (type == JobDocFilterType.Category)
  107. {
  108. var list = fullListShells.Where(x => x.DocSetCategory.Equals(text));
  109. foreach (var v in list)
  110. CheckDuplicateAndAdd(v);
  111. }
  112. else if (type == JobDocFilterType.Area)
  113. {
  114. var list = fullListShells.Where(x => x.DocSetArea.Equals(text));
  115. foreach (var v in list)
  116. CheckDuplicateAndAdd(v);
  117. }
  118. }
  119. private void CheckDuplicateAndAdd(JobDocSetFileShell v)
  120. {
  121. var duplicate = filteredShells.FirstOrDefault(x => x.ID == v.ID);
  122. if (duplicate == null)
  123. filteredShells.Add(v);
  124. }
  125. #endregion
  126. #region TreeView / Folder Interaction
  127. void Folder_Tapped(object sender, EventArgs e)
  128. {
  129. DisplayFolderContents();
  130. }
  131. private void DisplayFolderContents()
  132. {
  133. if (treeView.SelectedItem == null)
  134. {
  135. DisplayAlert("Info", "Please select a folder or All folders", "OK");
  136. return;
  137. }
  138. var folder = treeView.SelectedItem as FolderViewItem;
  139. if (folder.Documents == 0)
  140. return;
  141. if (specificQueryLoading)
  142. return;
  143. if (filesLoaded)
  144. {
  145. if (folder.ItemName == "All")
  146. {
  147. if (filters.Count != 0)
  148. AddSearchItems(filteredShells);
  149. else
  150. AddSearchItems(fullListShells);
  151. }
  152. else
  153. {
  154. if (filters.Count != 0)
  155. {
  156. var list = filteredShells.Where(x => x.FolderID == folder.ID);
  157. AddSearchItems(list);
  158. }
  159. else
  160. {
  161. var list = fullListShells.Where(x => x.FolderID == folder.ID);
  162. AddSearchItems(list);
  163. }
  164. }
  165. }
  166. else if (loadedFolders.Contains(folder.ID))
  167. {
  168. var list = specificQueryFileShells.Where(x => x.FolderID == folder.ID);
  169. AddSearchItems(list);
  170. }
  171. else
  172. LoadFilesForFolder(folder.ID);
  173. }
  174. private async void LoadFilesForFolder(Guid folderID)
  175. {
  176. currentQueryFileShells.Clear();
  177. specificQueryLoading = true;
  178. ShowLoading();
  179. LoadFiles(new Filter<JobDocumentSetMileStone>(x => x.DocumentSet.Folder.ID).IsEqualTo(folderID), true, folderID);
  180. }
  181. void Expand_Tapped(object sender, EventArgs e)
  182. {
  183. if (!foldersLoaded)
  184. return;
  185. treeViewFrame.HeightRequest = 28 * folderList.Count;
  186. expandImg.IsVisible = false;
  187. collapseImg.IsVisible = true;
  188. }
  189. void Collapse_Tapped(object sender, EventArgs e)
  190. {
  191. treeViewFrame.HeightRequest = 120;
  192. expandImg.IsVisible = true;
  193. collapseImg.IsVisible = false;
  194. }
  195. #endregion
  196. #region Searching
  197. private void SearchEnt_Changed(object sender, EventArgs e)
  198. {
  199. if (specificQueryLoading)
  200. return;
  201. RunSearch();
  202. }
  203. private void AddSearchItems(IEnumerable<JobDocSetFileShell> list)
  204. {
  205. searchList.Clear();
  206. foreach (var v in list)
  207. {
  208. searchList.Add(v);
  209. }
  210. RunSearch();
  211. }
  212. private void RunSearch()
  213. {
  214. Device.BeginInvokeOnMainThread(() =>
  215. {
  216. listView.ItemsSource = null;
  217. if (string.IsNullOrWhiteSpace(searchEnt.Text))
  218. {
  219. listView.ItemsSource = searchList;
  220. fileCountLbl.Text = "Files (" + searchList.Count() + ")";
  221. }
  222. else
  223. {
  224. var list = searchList.Where(x =>
  225. x.FileName.ToUpper().Contains(searchEnt.Text.ToUpper())
  226. || x.DocSetDescription.ToUpper().Contains(searchEnt.Text.ToUpper())
  227. || x.DocSetDescription.ToUpper().Contains(searchEnt.Text.ToUpper())
  228. || x.Issued.ToUpper().Contains(searchEnt.Text.ToUpper())
  229. || x.TrimmedIssued.ToUpper().Contains(searchEnt.Text.ToUpper())
  230. );
  231. listView.ItemsSource = list;
  232. fileCountLbl.Text = "Files (" + list.Count() + ")";
  233. }
  234. });
  235. }
  236. #endregion
  237. #region Loading
  238. private void TreeView_QueryNodeSize(object sender, Syncfusion.XForms.TreeView.QueryNodeSizeEventArgs e)
  239. {
  240. e.Height = e.GetActualNodeHeight();
  241. e.Handled = true;
  242. }
  243. private void LoadFolders(Guid jobid)
  244. {
  245. Task.Run(() =>
  246. {
  247. CoreTable table = QueryJobDocumentSetFolders(jobid);
  248. while (table == null)
  249. table = QueryJobDocumentSetFolders(jobid);
  250. Device.BeginInvokeOnMainThread(() =>
  251. {
  252. foreach (CoreRow row in table.Rows)
  253. {
  254. FolderViewItem folderItem = new FolderViewItem
  255. {
  256. ID = row.Get<Guid>("ID"),
  257. ParentID = row.Get<Guid>("Parent.ID"),
  258. ItemName = row.Get<string>("Name"),
  259. Documents = row.Get<int>("Documents")
  260. };
  261. folderList.Add(folderItem);
  262. }
  263. foreach (var folder in folderList)
  264. {
  265. folder.List = folderList;
  266. if (folder.ParentID == Guid.Empty || folder.ParentID == CoreUtils.FullGuid)
  267. displayList.Add(folder);
  268. }
  269. displayList = new ObservableCollection<FolderViewItem>(displayList.OrderBy(x => x.ItemName));
  270. treeView.ItemsSource = displayList;
  271. foldersLoaded = true;
  272. filterBtn.IsEnabled = true;
  273. });
  274. });
  275. }
  276. private CoreTable QueryJobDocumentSetFolders(Guid jobid)
  277. {
  278. try
  279. {
  280. return new Client<JobDocumentSetFolder>().Query(new Filter<JobDocumentSetFolder>(x => x.Job.ID).IsEqualTo(jobid),
  281. new Columns<JobDocumentSetFolder>(x => x.ID, x => x.Parent.ID, x => x.Name, x => x.Documents));
  282. }
  283. catch (Exception ex)
  284. {
  285. InABox.Mobile.MobileLogging.Log(ex);
  286. return null;
  287. }
  288. }
  289. private void LoadFiles(Filter<JobDocumentSetMileStone> filter, bool specificQuery = false, Guid loadFolder = new Guid())
  290. {
  291. Task.Run(() =>
  292. {
  293. try
  294. {
  295. filter = filter.And(x => x.Status).IsEqualTo(JobDocumentSetMileStoneStatus.Approved)
  296. .And(x => x.Type.SiteVisible).IsEqualTo(true);
  297. CoreTable milestones = QueryJobDocumentSetMileStone(filter);
  298. while (milestones == null)
  299. milestones = QueryJobDocumentSetMileStone(filter);
  300. if (milestones.Rows.Any())
  301. {
  302. var table = QueryFiles(milestones, specificQuery);
  303. if (table.Rows.Any())
  304. {
  305. foreach (CoreRow filerow in table.Rows)
  306. {
  307. AddFileShell(filerow, specificQuery);
  308. }
  309. Device.BeginInvokeOnMainThread(() =>
  310. {
  311. if (specificQuery)
  312. {
  313. ShowFiles();
  314. specificQueryLoading = false;
  315. loadedFolders.Add(loadFolder);
  316. AddSearchItems(currentQueryFileShells);
  317. }
  318. else
  319. {
  320. filesLoaded = true;
  321. displayList.Insert(0, new FolderViewItem { ItemName = "All", Documents = fullListShells.Count });
  322. folderList.Insert(0, new FolderViewItem { ItemName = "All", Documents = fullListShells.Count });
  323. treeView.ItemsSource = null;
  324. treeView.ItemsSource = displayList;
  325. }
  326. });
  327. }
  328. }
  329. else
  330. {
  331. specificQueryLoading = false;
  332. ShowFiles();
  333. }
  334. }
  335. catch
  336. {
  337. specificQueryLoading = false;
  338. ShowFiles();
  339. }
  340. });
  341. }
  342. private CoreTable QueryJobDocumentSetMileStone(Filter<JobDocumentSetMileStone> filter)
  343. {
  344. try
  345. {
  346. return new Client<JobDocumentSetMileStone>().Query(filter,
  347. new Columns<JobDocumentSetMileStone>(
  348. x => x.ID,
  349. x => x.DocumentSet.Folder.Name,
  350. x => x.DocumentSet.Folder.ID,
  351. x => x.DocumentSet.Type.Description,
  352. x => x.DocumentSet.Category.Description,
  353. x => x.DocumentSet.Discipline.Description,
  354. x => x.DocumentSet.Area.Description,
  355. x => x.Submitted,
  356. x => x.Employee.Name,
  357. x => x.Type.Description,
  358. x => x.DocumentSet.Description
  359. )
  360. );
  361. }
  362. catch (Exception ex)
  363. {
  364. InABox.Mobile.MobileLogging.Log(ex);
  365. return null;
  366. }
  367. }
  368. private CoreTable QueryFiles(CoreTable milestones, bool specificQuery = false)
  369. {
  370. Filter<JobDocumentSetMileStoneFile> filter = new Filter<JobDocumentSetMileStoneFile>(x => x.EntityLink.ID).IsEqualTo(milestones.Rows.FirstOrDefault().Get<Guid>("ID"));
  371. foreach (CoreRow milestonerow in milestones.Rows)
  372. {
  373. Guid id = AddMileStoneShell(milestonerow, specificQuery);
  374. filter = filter.Or(x => x.EntityLink.ID).IsEqualTo(milestonerow.Get<Guid>("ID"));
  375. }
  376. CoreTable table = DoQueryFiles(filter);
  377. while (table == null)
  378. table = DoQueryFiles(filter);
  379. return table;
  380. }
  381. private CoreTable DoQueryFiles(Filter<JobDocumentSetMileStoneFile> filter)
  382. {
  383. try
  384. {
  385. return new Client<JobDocumentSetMileStoneFile>().Query(
  386. filter,
  387. new Columns<JobDocumentSetMileStoneFile>(
  388. x => x.ID,
  389. x => x.DocumentLink.ID,
  390. x => x.Thumbnail,
  391. x => x.DocumentLink.FileName,
  392. x => x.EntityLink.ID
  393. ));
  394. }
  395. catch (Exception ex)
  396. {
  397. InABox.Mobile.MobileLogging.Log(ex);
  398. return null;
  399. }
  400. }
  401. private Guid AddMileStoneShell(CoreRow milestonerow, bool specificQuery = false)
  402. {
  403. Guid id = milestonerow.Get<Guid>("ID");
  404. MileStoneShell shell = new MileStoneShell
  405. {
  406. ID = milestonerow.Get<Guid>("ID"),
  407. FolderName = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.DocumentSet.Folder.Name),
  408. FolderID = milestonerow.Get<JobDocumentSetMileStone, Guid>(x => x.DocumentSet.Folder.ID),
  409. EmployeeName = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.Employee.Name),
  410. Type = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.Type.Description),
  411. DocSetDescription = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.DocumentSet.Description),
  412. Issued = "Submitted: " + milestonerow.Get<JobDocumentSetMileStone, DateTime>(x => x.Submitted).ToString("dd MMM yy"),
  413. DocSetType = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.DocumentSet.Type.Description),
  414. DocSetCategory = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.DocumentSet.Category.Description),
  415. DocSetDiscipline = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.DocumentSet.Discipline.Description),
  416. DocSetArea = milestonerow.Get<JobDocumentSetMileStone, string>(x => x.DocumentSet.Area.Description),
  417. };
  418. if (specificQuery)
  419. specificQueryMileStones.Add(shell);
  420. else
  421. mileStoneShells.Add(shell);
  422. return id;
  423. }
  424. private void AddFileShell(CoreRow filerow, bool specificQuery = false)
  425. {
  426. JobDocSetFileShell file = new JobDocSetFileShell
  427. {
  428. ID = filerow.Get<JobDocumentSetMileStoneFile, Guid>(x => x.ID),
  429. DocLinkID = filerow.Get<JobDocumentSetMileStoneFile, Guid>(x => x.DocumentLink.ID),
  430. FileName = filerow.Get<JobDocumentSetMileStoneFile, string>(x => x.DocumentLink.FileName),
  431. MileStoneID = filerow.Get<JobDocumentSetMileStoneFile, Guid>(x => x.EntityLink.ID)
  432. };
  433. MileStoneShell mileStone = mileStoneShells.Find(x => x.ID == file.MileStoneID);
  434. file.FolderName = mileStone.FolderName;
  435. file.FolderID = mileStone.FolderID;
  436. file.EmployeeName = mileStone.EmployeeName;
  437. file.Type = mileStone.Type;
  438. file.DocSetDescription = mileStone.DocSetDescription;
  439. file.Issued = mileStone.Issued;
  440. file.DocSetCategory = mileStone.DocSetCategory;
  441. file.DocSetType = mileStone.DocSetType;
  442. file.DocSetDiscipline = mileStone.DocSetDiscipline;
  443. file.DocSetArea = mileStone.DocSetArea;
  444. file.TrimmedIssued = TrimWhiteSpace(file.Issued);
  445. byte[] data = filerow.Get<byte[]>("Thumbnail");
  446. if (data != null)
  447. {
  448. file.ImageSource = ImageSource.FromStream(() => new MemoryStream(data));
  449. if (idiom == DeviceIdiom.Tablet)
  450. {
  451. file.HeightRequest = 400;
  452. file.WidthRequest = 500;
  453. }
  454. file.Thumbnail = data;
  455. }
  456. if (specificQuery)
  457. {
  458. specificQueryFileShells.Add(file);
  459. currentQueryFileShells.Add(file);
  460. }
  461. else
  462. fullListShells.Add(file);
  463. }
  464. private void ShowFiles()
  465. {
  466. Device.BeginInvokeOnMainThread(() =>
  467. {
  468. treeView.IsEnabled = true;
  469. loadingLayout.IsVisible = false;
  470. loadingColumn.Width = 0;
  471. filesLayout.IsVisible = true;
  472. filesColumn.Width = new GridLength(1, GridUnitType.Star);
  473. });
  474. }
  475. private void ShowLoading()
  476. {
  477. Device.BeginInvokeOnMainThread(async () =>
  478. {
  479. treeView.IsEnabled = false;
  480. filesLayout.IsVisible = false;
  481. filesColumn.Width = 0;
  482. loadingLayout.IsVisible = true;
  483. loadingColumn.Width = new GridLength(1, GridUnitType.Star);
  484. Random random = new Random();
  485. uint number = (uint)random.Next(500, 3000);
  486. await loadingLbl.TranslateTo(0, 15, 500);
  487. await loadingLbl.TranslateTo(0, 0, 500);
  488. loadingLbl.RotateTo(360, number);
  489. await loadingLbl.TranslateTo(0, 15, 500);
  490. await loadingLbl.TranslateTo(0, 0, 500);
  491. await loadingLbl.TranslateTo(0, 15, 500);
  492. await loadingLbl.TranslateTo(0, 0, 500);
  493. await loadingLbl.TranslateTo(0, 15, 500);
  494. number = (uint)random.Next(500, 3000);
  495. await loadingLbl.TranslateTo(0, 0, 500);
  496. loadingLbl.RotateTo(360, number);
  497. });
  498. }
  499. static string TrimWhiteSpace(string s)
  500. {
  501. s = String.Concat(s.Where(c => !Char.IsWhiteSpace(c)));
  502. return s;
  503. }
  504. #endregion
  505. #region ListView Interaction
  506. void List_Tapped(object sender, EventArgs e)
  507. {
  508. var shell = listView.SelectedItem as JobDocSetFileShell;
  509. if (Device.RuntimePlatform.Equals(Device.Android) && PRSSecurity.IsAllowed<CanOpenMobileNativePDFViewer>())
  510. OpenNativeViewer(shell.DocLinkID);
  511. else
  512. {
  513. PDFViewer viewer = new PDFViewer(shell.DocLinkID);
  514. Navigation.PushAsync(viewer);
  515. }
  516. }
  517. private async void OpenNativeViewer(Guid docID)
  518. {
  519. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(docID),
  520. new Columns<Document>(x => x.Data, x => x.FileName));
  521. Document doc = table.Rows.First().ToObject<Document>();
  522. var filePath = Path.Combine(FileSystem.AppDataDirectory, doc.FileName);
  523. File.WriteAllBytes(filePath, doc.Data);
  524. await Launcher.OpenAsync(new OpenFileRequest
  525. {
  526. File = new ReadOnlyFile(filePath)
  527. });
  528. }
  529. void Image_Tapped(object sender, EventArgs e)
  530. {
  531. var shell = ((TappedEventArgs)e).Parameter as JobDocSetFileShell;
  532. if (shell == null)
  533. return;
  534. if (shell.Thumbnail != null)
  535. {
  536. Image popupContent = new Image();
  537. popupContent.HeightRequest = 500;
  538. popupContent.WidthRequest = 600;
  539. popupContent.HorizontalOptions = LayoutOptions.FillAndExpand;
  540. popupContent.VerticalOptions = LayoutOptions.FillAndExpand;
  541. popupContent.Aspect = Aspect.AspectFit;
  542. popupContent.Source = ImageSource.FromStream(() => new MemoryStream(shell.Thumbnail));
  543. popupLayout.PopupView.ShowHeader = false;
  544. popupLayout.PopupView.ShowFooter = false;
  545. popupLayout.PopupView.ContentTemplate = new DataTemplate(() =>
  546. {
  547. return popupContent;
  548. });
  549. popupLayout.Show();
  550. }
  551. }
  552. #endregion
  553. }
  554. #region Classes
  555. public class FolderViewItem : INotifyPropertyChanged
  556. {
  557. public event OnFolderListChanged OnFolderListChanged;
  558. public event PropertyChangedEventHandler PropertyChanged;
  559. public Guid ID { get; set; }
  560. public Guid ParentID { get; set; }
  561. public ImageSource ImageIcon { get; set; }
  562. private ObservableCollection<FolderViewItem> list;
  563. public ObservableCollection<FolderViewItem> List
  564. {
  565. get
  566. {
  567. return list;
  568. }
  569. set
  570. {
  571. list = value;
  572. OnFolderListChanged?.Invoke();
  573. }
  574. }
  575. private string itemName;
  576. public string ItemName
  577. {
  578. get { return itemName; }
  579. set
  580. {
  581. itemName = value;
  582. RaisedOnPropertyChanged("ItemName");
  583. }
  584. }
  585. public int Documents { get; set; }
  586. public ObservableCollection<FolderViewItem> SubFiles { get; set; }
  587. public Guid DocID { get; set; }
  588. public FolderViewItem()
  589. {
  590. ID = Guid.Empty;
  591. ItemName = "";
  592. ImageIcon = "folder.png";
  593. DocID = Guid.Empty;
  594. ParentID = Guid.Empty;
  595. OnFolderListChanged += FolderViewItem_OnFolderListChanged;
  596. Documents = 0;
  597. }
  598. private void FolderViewItem_OnFolderListChanged()
  599. {
  600. GetChildren();
  601. }
  602. public void RaisedOnPropertyChanged(string _PropertyName)
  603. {
  604. if (PropertyChanged != null)
  605. {
  606. PropertyChanged(this, new PropertyChangedEventArgs(_PropertyName));
  607. }
  608. }
  609. private void GetChildren()
  610. {
  611. SubFiles = new ObservableCollection<FolderViewItem>(list.Where(x => x.ParentID.Equals(ID)));
  612. }
  613. }
  614. public class MileStoneShell
  615. {
  616. public Guid ID { get; set; }
  617. public string FolderName { get; set; }
  618. public Guid FolderID { get; set; }
  619. public string EmployeeName { get; set; }
  620. public string Type { get; set; }
  621. public string DocSetDescription { get; set; }
  622. public string Issued { get; set; }
  623. public string DocSetType { get; set; }
  624. public string DocSetDiscipline { get; set; }
  625. public string DocSetCategory { get; set; }
  626. public string DocSetArea { get; set; }
  627. public MileStoneShell()
  628. {
  629. ID = Guid.Empty;
  630. FolderID = Guid.Empty;
  631. FolderName = "";
  632. EmployeeName = "";
  633. Type = "";
  634. DocSetDescription = "";
  635. Issued = "";
  636. DocSetCategory = "";
  637. DocSetDiscipline = "";
  638. DocSetType = "";
  639. DocSetArea = "";
  640. }
  641. }
  642. public class JobDocSetFileShell
  643. {
  644. public Guid ID { get; set; }
  645. public Guid DocLinkID { get; set; }
  646. public string FileName { get; set; }
  647. public string FolderName { get; set; }
  648. public Guid FolderID { get; set; }
  649. public string EmployeeName { get; set; }
  650. public string Type { get; set; }
  651. public string DocSetDescription { get; set; }
  652. public string Issued { get; set; }
  653. public string TrimmedIssued { get; set; }
  654. public ImageSource ImageSource { get; set; }
  655. public double HeightRequest { get; set; }
  656. public double WidthRequest { get; set; }
  657. public byte[] Thumbnail { get; set; }
  658. public Guid MileStoneID { get; set; }
  659. public string DocSetType { get; set; }
  660. public string DocSetDiscipline { get; set; }
  661. public string DocSetCategory { get; set; }
  662. public string DocSetArea { get; set; }
  663. public JobDocSetFileShell()
  664. {
  665. ID = Guid.Empty;
  666. DocLinkID = Guid.Empty;
  667. FileName = "";
  668. FolderName = "";
  669. EmployeeName = "";
  670. Type = "";
  671. DocSetDescription = "";
  672. ImageSource = null;
  673. Issued = "";
  674. TrimmedIssued = "";
  675. HeightRequest = 150;
  676. WidthRequest = 200;
  677. Thumbnail = null;
  678. MileStoneID = Guid.Empty;
  679. FolderID = Guid.Empty;
  680. DocSetCategory = "";
  681. DocSetDiscipline = "";
  682. DocSetType = "";
  683. DocSetArea = "";
  684. }
  685. }
  686. public enum JobDocFilterType
  687. {
  688. Discipline,
  689. Type,
  690. Category,
  691. Area
  692. }
  693. #endregion
  694. }