PDFList.xaml.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. using Comal.Classes;
  2. using InABox.Clients;
  3. using InABox.Core;
  4. using Syncfusion.SfPdfViewer.XForms;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. using Xamarin.Essentials;
  11. using Xamarin.Forms;
  12. using Xamarin.Forms.Xaml;
  13. using XF.Material.Forms.UI.Dialogs;
  14. using Document = InABox.Core.Document;
  15. namespace comal.timesheets
  16. {
  17. [XamlCompilation(XamlCompilationOptions.Compile)]
  18. public partial class PDFList : ContentPage
  19. {
  20. List<DocShell> pDFShells = new List<DocShell>();
  21. bool bAllowPrintShare;
  22. bool bAllowDelete;
  23. bool bAllowView = true;
  24. Entity Entity;
  25. DeviceIdiom DeviceIdiom;
  26. //allowing of print/share is disabled by default
  27. //allowing of upload is disabled by default
  28. public PDFList(Dictionary<string, Guid> fileNameIDs, bool allowprintshare = false)
  29. {
  30. InitializeComponent();
  31. NavigationPage.SetHasBackButton(this, false);
  32. bAllowPrintShare = allowprintshare;
  33. LoadScreen(fileNameIDs);
  34. }
  35. //2nd constructor requires an entity for uploading of files or deleting (if allowed)
  36. public PDFList(Dictionary<string, Guid> fileNameIDs, Entity entity, bool allowprintshare = false, bool allowUpload = false, bool allowDelete = false, bool allowView = true)
  37. {
  38. InitializeComponent();
  39. NavigationPage.SetHasBackButton(this, false);
  40. bAllowPrintShare = allowprintshare;
  41. Entity = entity;
  42. if (allowUpload)
  43. uploadBtn.IsVisible = true;
  44. bAllowDelete = allowDelete;
  45. bAllowView = allowView;
  46. LoadScreen(fileNameIDs);
  47. }
  48. //Loading from site module
  49. public PDFList(Guid jobID)
  50. {
  51. InitializeComponent();
  52. NavigationPage.SetHasBackButton(this, false);
  53. DeviceIdiom = DeviceInfo.Idiom;
  54. LoadMileStones(jobID);
  55. }
  56. //standard load
  57. private void LoadScreen(Dictionary<string, Guid> fileNameIDs)
  58. {
  59. foreach (KeyValuePair<string, Guid> pair in fileNameIDs)
  60. {
  61. DocShell shell = new DocShell();
  62. shell.FileName = pair.Key;
  63. shell.DocID = pair.Value;
  64. shell = AssignIcon(shell);
  65. pDFShells.Add(shell);
  66. }
  67. pdfListView.ItemsSource = pDFShells;
  68. }
  69. //load from site module
  70. private async void LoadMileStones(Guid jobID)
  71. {
  72. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  73. {
  74. CoreTable table = new Client<JobDocumentSetMileStone>().Query(
  75. new Filter<JobDocumentSetMileStone>(x => x.DocumentSet.Job.ID).IsEqualTo(jobID)
  76. .And(x => x.Status).IsEqualTo(JobDocumentSetMileStoneStatus.Submitted)
  77. .And(x => x.Type.SiteVisible).IsEqualTo(true),
  78. new Columns<JobDocumentSetMileStone>(
  79. x => x.ID, //0
  80. x => x.Type.Description, //1
  81. x => x.Submitted, //2
  82. x => x.Employee.Name //3
  83. ));
  84. foreach (CoreRow row in table.Rows)
  85. {
  86. LoadFilesForMileStone(row);
  87. }
  88. pdfListView.ItemsSource = pDFShells;
  89. }
  90. }
  91. private void LoadFilesForMileStone(CoreRow row)
  92. {
  93. List<object> list = row.Values;
  94. if (list[0] == null) list[0] = Guid.Empty; //0
  95. if (list[1] == null) list[1] = ""; //1
  96. if (list[2] == null) list[2] = DateTime.MinValue; //2
  97. if (list[3] == null) list[3] = ""; //3
  98. Guid id = Guid.Parse(list[0].ToString());
  99. string type = list[1].ToString();
  100. string date = DateTime.Parse(list[2].ToString()).ToString("dd MMM yy");
  101. string empName = list[3].ToString();
  102. string fileDetails = "Issued: " + date + Environment.NewLine + "By " + empName;
  103. CoreTable fileTable = new Client<JobDocumentSetMileStoneFile>().Query
  104. (
  105. new Filter<JobDocumentSetMileStoneFile>(x => x.EntityLink.ID).IsEqualTo(id),
  106. new Columns<JobDocumentSetMileStoneFile>(x => x.DocumentLink.ID, x => x.Thumbnail, x => x.DocumentLink.FileName)
  107. );
  108. foreach (CoreRow fileTableRow in fileTable.Rows)
  109. {
  110. List<object> fileTableList = fileTableRow.Values;
  111. DocShell shell = new DocShell();
  112. shell.FirstRowHeight = 30;
  113. shell.Type = type;
  114. shell.FileName = fileTableRow.Values[2].ToString();
  115. shell.DocID = Guid.Parse(fileTableRow.Values[0].ToString());
  116. shell.FileDetails = shell.FileName + Environment.NewLine + fileDetails;
  117. if (fileTableRow.Values[1] != null)
  118. {
  119. shell.ThumbNail = fileTableRow.Get<byte[]>("Thumbnail");
  120. shell = AssignThumbnail(shell);
  121. }
  122. else
  123. shell = AssignIcon(shell);
  124. pDFShells.Add(shell);
  125. }
  126. }
  127. private DocShell AssignThumbnail(DocShell shell)
  128. {
  129. shell.ImageRow = 0;
  130. shell.ImageRowSpan = 2;
  131. shell.ImageSource = ImageSource.FromStream(() => new MemoryStream(shell.ThumbNail));
  132. shell.TypeColumn = 1;
  133. shell.TypeColumnSpan = 1;
  134. if (DeviceIdiom == DeviceIdiom.Tablet)
  135. {
  136. shell.ImageHeightRequest = 300;
  137. shell.ImageWidthRequest = 400;
  138. shell.ColumnWidth = 400;
  139. }
  140. else
  141. {
  142. shell.ImageHeightRequest = 150;
  143. shell.ImageWidthRequest = 200;
  144. shell.ColumnWidth = 200;
  145. shell.ExpandVisible = true;
  146. }
  147. return shell;
  148. }
  149. private DocShell AssignIcon(DocShell shell)
  150. {
  151. if (shell.FileName.ToLower().EndsWith("pdf"))
  152. shell.ImageSource = "pdficon.png";
  153. else if (shell.FileName.ToLower().EndsWith("docx") || shell.FileName.ToLower().EndsWith("doc"))
  154. shell.ImageSource = "worddoc.png";
  155. else if (shell.FileName.ToLower().EndsWith("png") || shell.FileName.ToLower().EndsWith("jpg"))
  156. shell.ImageSource = "productimage.png";
  157. return shell;
  158. }
  159. private void ExpandImage_Tapped(object sender, EventArgs e)
  160. {
  161. var item = ((TappedEventArgs)e).Parameter as DocShell;
  162. if (item == null)
  163. return;
  164. }
  165. void ExitBtn_Clicked(object sender, EventArgs e)
  166. {
  167. Navigation.PopAsync();
  168. }
  169. private async void Upload_Clicked(object sender, EventArgs e)
  170. {
  171. var result = await FilePicker.PickAsync(new PickOptions { FileTypes = FilePickerFileType.Pdf });
  172. if (result != null)
  173. {
  174. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  175. {
  176. string fileName = $"File Name: {result.FileName}";
  177. var stream = await result.OpenReadAsync();
  178. var memoryStream = new MemoryStream();
  179. stream.CopyTo(memoryStream);
  180. var data = memoryStream.ToArray();
  181. var doc = new Document { FileName = fileName, Data = data };
  182. new Client<Document>().Save(doc, "Uploaded from mobile device");
  183. pDFShells.Add(new DocShell { FileName = fileName, DocID = doc.ID });
  184. pdfListView.ItemsSource = null;
  185. pdfListView.ItemsSource = pDFShells;
  186. SaveEntityDoc(doc.ID);
  187. }
  188. }
  189. }
  190. private void SaveEntityDoc(Guid docID)
  191. {
  192. if (Entity is EmployeeQualification)
  193. {
  194. EmployeeQualificationDocument empDoc = new EmployeeQualificationDocument();
  195. empDoc.DocumentLink.ID = docID;
  196. empDoc.EntityLink.ID = Entity.ID;
  197. new Client<EmployeeQualificationDocument>().Save(empDoc, "Upload from mobile device");
  198. }
  199. if (Entity is Notification)
  200. {
  201. NotificationDocument notificationDoc = new NotificationDocument();
  202. notificationDoc.DocumentLink.ID = docID;
  203. notificationDoc.EntityLink.ID = Entity.ID;
  204. new Client<NotificationDocument>().Save(notificationDoc, "Upload from mobile device");
  205. }
  206. }
  207. private async void List_Tapped(object sender, EventArgs e)
  208. {
  209. DocShell shell = pdfListView.SelectedItem as DocShell;
  210. if (!bAllowView)
  211. {
  212. DisplayAlert("Alert", "Opening is not allowed from this module", "OK");
  213. return;
  214. }
  215. if (bAllowDelete)
  216. {
  217. string chosenOption = await DisplayActionSheet("Choose an option", "Cancel", null, "View", "Delete File");
  218. switch (chosenOption)
  219. {
  220. case "Cancel":
  221. return;
  222. default:
  223. return;
  224. case "View":
  225. OpenDocViewer(shell);
  226. break;
  227. case "Delete File":
  228. ConfirmDelete(shell);
  229. break;
  230. }
  231. }
  232. else
  233. {
  234. OpenDocViewer(shell);
  235. }
  236. }
  237. private async void ConfirmDelete(DocShell shell)
  238. {
  239. string chosenOption = await DisplayActionSheet("Confirm Delete?", "Cancel", null, "Yes", "No");
  240. switch (chosenOption)
  241. {
  242. case "Cancel":
  243. return;
  244. default:
  245. return;
  246. case "No":
  247. return;
  248. case "Yes":
  249. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Working"))
  250. {
  251. pDFShells.Remove(shell);
  252. pdfListView.ItemsSource = null;
  253. pdfListView.ItemsSource = pDFShells;
  254. Document document = new Document { ID = shell.DocID };
  255. DeleteEntityDocument(shell.DocID);
  256. new Client<Document>().Delete(document, "Deleted from mobile device");
  257. }
  258. break;
  259. }
  260. }
  261. void DeleteEntityDocument(Guid id)
  262. {
  263. if (Entity is EmployeeQualification)
  264. {
  265. CoreTable table = new Client<EmployeeQualificationDocument>().Query(new Filter<EmployeeQualificationDocument>(x => x.DocumentLink.ID).IsEqualTo(id),
  266. new Columns<EmployeeQualificationDocument>(x => x.ID));
  267. EmployeeQualificationDocument empDoc = new EmployeeQualificationDocument();
  268. empDoc.ID = Guid.Parse(table.Rows.First().Values[0].ToString());
  269. new Client<EmployeeQualificationDocument>().Delete(empDoc, "Deleted from mobile device");
  270. }
  271. }
  272. void OpenDocViewer(DocShell shell)
  273. {
  274. shell.FileName = shell.FileName.ToLower();
  275. if (shell.FileName.EndsWith("pdf"))
  276. {
  277. PDFViewer viewer = new PDFViewer(shell.DocID, bAllowPrintShare);
  278. Navigation.PushAsync(viewer);
  279. }
  280. else if (shell.FileName.EndsWith("docx") || shell.FileName.EndsWith("doc"))
  281. {
  282. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(shell.DocID),
  283. new Columns<Document>(x => x.Data));
  284. Document doc = table.Rows.First().ToObject<Document>();
  285. MemoryStream memoryStream = new MemoryStream(doc.Data);
  286. DisplayAlert("Error", "Word documents not available at this time", "OK");
  287. }
  288. else if (shell.FileName.EndsWith("png") || shell.FileName.EndsWith("jpg") || shell.FileName.EndsWith("jpeg"))
  289. {
  290. CoreTable table = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(shell.DocID),
  291. new Columns<Document>(x => x.Data));
  292. Document doc = table.Rows.First().ToObject<Document>();
  293. ImageSource src = ImageSource.FromStream(() => new MemoryStream(doc.Data));
  294. ImageViewer viewer = new ImageViewer(src);
  295. Navigation.PushAsync(viewer);
  296. }
  297. }
  298. void SearchEnt_Changed(object sender, EventArgs e)
  299. {
  300. pdfListView.ItemsSource = pDFShells.Where(x =>
  301. x.FileName.Contains(searchEnt.Text) || x.FileName.Contains(searchEnt.Text.ToLower())
  302. || x.FileName.Contains(searchEnt.Text.ToUpper()) || x.FileName.Contains(UpperCaseFirst(searchEnt.Text))
  303. );
  304. }
  305. static String UpperCaseFirst(string s)
  306. {
  307. char[] a = s.ToCharArray();
  308. a[0] = char.ToUpper(a[0]);
  309. return new string(a);
  310. }
  311. }
  312. public class DocShell
  313. {
  314. public string FileName { get; set; }
  315. public Guid DocID { get; set; }
  316. public ImageSource ImageSource { get; set; }
  317. public double FirstRowHeight { get; set; }
  318. public string Type { get; set; }
  319. public double ImageHeightRequest { get; set; }
  320. public double ImageWidthRequest { get; set; }
  321. public double ColumnWidth { get; set; }
  322. public double ImageRow { get; set; }
  323. public double ImageRowSpan { get; set; }
  324. public byte[] ThumbNail { get; set; }
  325. public double TypeColumn { get; set; }
  326. public double TypeColumnSpan { get; set; }
  327. public string FileDetails { get; set; }
  328. public bool ExpandVisible { get; set; }
  329. public DocShell()
  330. {
  331. FileName = "";
  332. DocID = Guid.Empty;
  333. ImageSource = "";
  334. FirstRowHeight = 0;
  335. Type = "";
  336. ImageHeightRequest = 30;
  337. ImageWidthRequest = 30;
  338. ColumnWidth = 40;
  339. ImageRow = 1;
  340. ImageRowSpan = 1;
  341. TypeColumn = 0;
  342. TypeColumnSpan = 2;
  343. FileDetails = "";
  344. ExpandVisible = false;
  345. }
  346. }
  347. }