TasksList.xaml.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.ComponentModel;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using comal.timesheets.Tasks;
  8. using Comal.Classes;
  9. using InABox.Clients;
  10. using InABox.Configuration;
  11. using InABox.Core;
  12. using Xamarin.Forms;
  13. using Xamarin.Forms.Xaml;
  14. using XF.Material.Forms.UI;
  15. using XF.Material.Forms.UI.Dialogs;
  16. using System.Threading;
  17. namespace comal.timesheets
  18. {
  19. [XamlCompilation(XamlCompilationOptions.Compile)]
  20. public partial class TasksList : ContentPage
  21. {
  22. Color color = Color.FromHex("#15C7C1");
  23. List<KanbanSubscriberShell> kanbanSubscriberShells = new List<KanbanSubscriberShell>();
  24. List<KanbanSubscriberShell> searchList = new List<KanbanSubscriberShell>();
  25. int currentCategory = 0;
  26. bool searching = false;
  27. bool firstLoad = true;
  28. bool tapping = false;
  29. bool doubleTap = false;
  30. public TasksList()
  31. {
  32. InitializeComponent();
  33. LoadPreferences();
  34. }
  35. private void LoadPreferences()
  36. {
  37. try
  38. {
  39. if (!App.Current.Properties.ContainsKey("ObserverPreference"))
  40. {
  41. App.Current.Properties.Add("ObserverPreference", "True");
  42. observerSwitch.IsToggled = true;
  43. }
  44. else
  45. {
  46. observerSwitch.IsToggled = Convert.ToBoolean(App.Current.Properties["ObserverPreference"]);
  47. }
  48. if (!App.Current.Properties.ContainsKey("PromptedOnUsage"))
  49. {
  50. App.Current.Properties.Add("PromptedOnUsage", "True");
  51. DisplayAlert("One-time Prompt:", "Single Tap to Open Task," + System.Environment.NewLine + "Double Tap to Complete Task", "OK");
  52. }
  53. }
  54. catch { }
  55. }
  56. protected override void OnAppearing()
  57. {
  58. LoadData();
  59. base.OnAppearing();
  60. }
  61. private async void LoadData()
  62. {
  63. try
  64. {
  65. searchEnt.IsEnabled = false;
  66. await Task.Run(() =>
  67. {
  68. kanbanSubscriberShells.Clear();
  69. CoreTable table = new Client<KanbanSubscriber>().Query(
  70. new Filter<KanbanSubscriber>(x => x.Employee.ID).IsEqualTo(GlobalVariables.EmpID)
  71. .And(x => x.Kanban.Closed).IsEqualTo(DateTime.MinValue).And(x => x.Kanban.Category).IsNotEqualTo("Complete"),
  72. new Columns<KanbanSubscriber>
  73. (
  74. x => x.Kanban.ID, //0
  75. x => x.Kanban.Number, //1
  76. x => x.Kanban.DueDate, //2
  77. x => x.Kanban.Title, //3
  78. x => x.Kanban.Summary, //4
  79. x => x.Kanban.Category, //5
  80. x => x.Kanban.ManagerLink.Name, //6
  81. x => x.Kanban.Attachments, //7
  82. x => x.Manager, //8
  83. x => x.Assignee, //9
  84. x => x.Kanban.Locked //10
  85. ),
  86. new SortOrder<KanbanSubscriber>(x => x.Kanban.DueDate));
  87. string emptyString = "";
  88. foreach (CoreRow row in table.Rows)
  89. {
  90. List<object> list = row.Values;
  91. if (list[0] == null) { list[0] = Guid.Empty; } //0
  92. if (list[1] == null) { list[1] = emptyString; } //1
  93. if (list[2] == null) { list[2] = DateTime.MinValue; } //2
  94. if (list[3] == null) { list[3] = emptyString; } //3
  95. if (list[4] == null) { list[4] = emptyString; } //4
  96. if (list[5] == null) { list[5] = emptyString; } //5
  97. if (list[6] == null) { list[6] = emptyString; } //6
  98. if (list[7] == null) { list[7] = 0; } //7
  99. if (list[8] == null) { list[8] = false; } //8
  100. if (list[9] == null) { list[9] = false; } //9
  101. if (list[10] == null) { list[10] = false; } //10
  102. KanbanSubscriberShell kanbanSubscriberShell = new KanbanSubscriberShell();
  103. kanbanSubscriberShell.ID = Guid.Parse(list[0].ToString());
  104. kanbanSubscriberShell.Number = list[1].ToString();
  105. kanbanSubscriberShell.DueDate = DateTime.Parse(list[2].ToString());
  106. kanbanSubscriberShell.Title = list[3].ToString();
  107. kanbanSubscriberShell.Summary = list[4].ToString();
  108. kanbanSubscriberShell.Category = ChooseCategory(list[5].ToString());
  109. kanbanSubscriberShell.ManagerName = list[6].ToString();
  110. kanbanSubscriberShell.Attachments = int.Parse(list[7].ToString());
  111. bool manager = Convert.ToBoolean(list[8].ToString());
  112. bool assignee = Convert.ToBoolean(list[9].ToString());
  113. kanbanSubscriberShell.Locked = Convert.ToBoolean(list[10].ToString());
  114. kanbanSubscriberShell.Color = ChooseColour(manager, assignee, kanbanSubscriberShell.DueDate);
  115. if (kanbanSubscriberShell.Attachments != 0)
  116. {
  117. kanbanSubscriberShell.ImagePath = "paperclip.png";
  118. if (Device.RuntimePlatform.Equals(Device.iOS)) kanbanSubscriberShell.ImagePath = "attachments.png";
  119. }
  120. if (kanbanSubscriberShell.Color == Color.FromHex("#cb99c9"))
  121. {
  122. kanbanSubscriberShell.IsObserver = true;
  123. }
  124. kanbanSubscriberShells.Add(kanbanSubscriberShell);
  125. }
  126. if (searching) RunSearch();
  127. else
  128. {
  129. RefreshButtons(kanbanSubscriberShells);
  130. DisplayList(kanbanSubscriberShells);
  131. }
  132. firstLoad = false;
  133. });
  134. }
  135. catch { }
  136. }
  137. private List<KanbanSubscriberShell> removeObservers(List<KanbanSubscriberShell> list)
  138. {
  139. try
  140. {
  141. if (App.Current.Properties["ObserverPreference"].Equals("True"))
  142. {
  143. return list;
  144. }
  145. else
  146. {
  147. var sublist = list.Where(x => x.IsObserver == false);
  148. List<KanbanSubscriberShell> newList = new List<KanbanSubscriberShell>();
  149. foreach (KanbanSubscriberShell shell in sublist)
  150. {
  151. newList.Add(shell);
  152. }
  153. return newList;
  154. }
  155. }
  156. catch { return new List<KanbanSubscriberShell>(); }
  157. }
  158. private void DisplayList(List<KanbanSubscriberShell> list)
  159. {
  160. try
  161. {
  162. list = removeObservers(list);
  163. Device.BeginInvokeOnMainThread(() =>
  164. {
  165. switch (currentCategory)
  166. {
  167. case 0:
  168. taskListView.ItemsSource = list.Where(x => x.Category == "To Do");
  169. break;
  170. case 1:
  171. taskListView.ItemsSource = list.Where(x => x.Category == "Current");
  172. break;
  173. case 2:
  174. taskListView.ItemsSource = list.Where(x => x.Category == "Waiting");
  175. break;
  176. }
  177. searchEnt.IsEnabled = true;
  178. observerSwitch.IsEnabled = true;
  179. });
  180. }
  181. catch { }
  182. }
  183. private void RefreshButtons(List<KanbanSubscriberShell> list)
  184. {
  185. try
  186. {
  187. list = removeObservers(list);
  188. Device.BeginInvokeOnMainThread(() =>
  189. {
  190. if (String.Equals(Device.RuntimePlatform, Device.iOS))
  191. {
  192. buttonToDo.Text = String.Format("{0} ({1})", "To Do", list.Count(x => x.Category == "To Do"));
  193. buttonCurrent.Text = String.Format("{0} ({1})", "Current", list.Count(x => x.Category == "Current"));
  194. buttonWaiting.Text = String.Format("{0} ({1})", "Waiting", list.Count(x => x.Category == "Waiting"));
  195. }
  196. else
  197. {
  198. buttonToDo.Text = "To Do (" + list.Count(x => x.Category == "To Do") + ")";
  199. buttonCurrent.Text = "Current (" + list.Count(x => x.Category == "Current") + ")";
  200. buttonWaiting.Text = "Waiting (" + list.Count(x => x.Category == "Waiting") + ")";
  201. }
  202. });
  203. }
  204. catch { }
  205. }
  206. private string ChooseCategory(string _category)
  207. {
  208. switch (_category)
  209. {
  210. case "Open":
  211. _category = "To Do";
  212. break;
  213. case "In Progress":
  214. _category = "Current";
  215. break;
  216. default:
  217. break;
  218. }
  219. return _category;
  220. }
  221. private void AddTask_Clicked(object sender, EventArgs e)
  222. {
  223. try
  224. {
  225. AddEditTask addEditTask = new AddEditTask();
  226. Navigation.PushAsync(addEditTask);
  227. }
  228. catch { }
  229. }
  230. async void KanbanList_Tapped(object sender, EventArgs e)
  231. {
  232. try
  233. {
  234. if (tapping)
  235. {
  236. doubleTap = true;
  237. var selectedTask = taskListView.SelectedItem as KanbanSubscriberShell;
  238. if (selectedTask.Locked)
  239. {
  240. doubleTap = false;
  241. DisplayAlert("Alert", "Unable to complete locked task", "Cancel");
  242. return;
  243. }
  244. string chosenOption = await DisplayActionSheet("Complete Task?", "Cancel", null, "Yes", "No");
  245. switch (chosenOption)
  246. {
  247. case "Cancel":
  248. break;
  249. case "No":
  250. break;
  251. case "Yes":
  252. CompleteTask(selectedTask);
  253. break;
  254. default:
  255. break;
  256. }
  257. doubleTap = false;
  258. }
  259. else
  260. {
  261. tapping = true;
  262. Timer t = new Timer(TimerCallBack, null, 750, Timeout.Infinite);
  263. }
  264. }
  265. catch { }
  266. }
  267. private async void CompleteTask(KanbanSubscriberShell shell)
  268. {
  269. try
  270. {
  271. kanbanSubscriberShells.Remove(shell);
  272. RefreshButtons(kanbanSubscriberShells);
  273. DisplayList(kanbanSubscriberShells);
  274. await Task.Run(() =>
  275. {
  276. CoreTable table = new Client<Kanban>().Query
  277. (
  278. new Filter<Kanban>(x => x.ID).IsEqualTo(shell.ID),
  279. new Columns<Kanban>(x => x.ID, x => x.Category)
  280. );
  281. Kanban kanban = table.Rows.First().ToObject<Kanban>();
  282. kanban.Category = "Complete";
  283. new Client<Kanban>().Save(kanban, "Completed from mobile device");
  284. });
  285. }
  286. catch { }
  287. }
  288. private async void TimerCallBack(object o) //for single tap
  289. {
  290. try
  291. {
  292. tapping = false;
  293. if (!doubleTap)
  294. {
  295. var selectedTask = taskListView.SelectedItem as KanbanSubscriberShell;
  296. string loadingMessage = "Loading Task " + selectedTask.Number;
  297. if (selectedTask.Attachments != 0)
  298. {
  299. loadingMessage = loadingMessage + " with " + selectedTask.Attachments + " attached document(s). Please wait for photos to appear.";
  300. }
  301. Device.BeginInvokeOnMainThread(async () =>
  302. {
  303. using (await MaterialDialog.Instance.LoadingDialogAsync(message: loadingMessage))
  304. {
  305. Guid ID = selectedTask.ID;
  306. var form = new AddEditTask(ID);
  307. await Navigation.PushAsync(form);
  308. }
  309. });
  310. }
  311. }
  312. catch { }
  313. }
  314. private async void SearchEnt_Changed(object sender, EventArgs e)
  315. {
  316. if (!string.IsNullOrWhiteSpace(searchEnt.Text))
  317. {
  318. searching = true;
  319. RunSearch();
  320. }
  321. else
  322. {
  323. searching = false;
  324. RefreshButtons(kanbanSubscriberShells);
  325. DisplayList(kanbanSubscriberShells);
  326. }
  327. }
  328. private async void RunSearch()
  329. {
  330. try
  331. {
  332. await Task.Run(() =>
  333. {
  334. searchList.Clear();
  335. var list = kanbanSubscriberShells.Where(x =>
  336. x.Number.Contains(searchEnt.Text) ||
  337. x.ManagerName.Contains(searchEnt.Text) || x.ManagerName.Contains(UpperCaseFirst(searchEnt.Text)) ||
  338. x.Title.Contains(searchEnt.Text) || x.Title.Contains(searchEnt.Text.ToUpper()) || x.Title.Contains(searchEnt.Text.ToLower()) || x.Title.Contains(UpperCaseFirst(searchEnt.Text)) ||
  339. x.Summary.Contains(searchEnt.Text) || x.Summary.Contains(searchEnt.Text.ToUpper()) || x.Summary.Contains(searchEnt.Text.ToLower()) || x.Summary.Contains(UpperCaseFirst(searchEnt.Text)) ||
  340. x.DueDate.ToString().Contains(searchEnt.Text) || x.DueDate.ToString().Contains(searchEnt.Text.ToUpper()) || x.DueDate.ToString().Contains(searchEnt.Text.ToLower()) || x.DueDate.ToString().Contains(UpperCaseFirst(searchEnt.Text))
  341. );
  342. foreach (KanbanSubscriberShell shell in list)
  343. {
  344. searchList.Add(shell);
  345. }
  346. RefreshButtons(searchList);
  347. DisplayList(searchList);
  348. });
  349. }
  350. catch { }
  351. }
  352. static String UpperCaseFirst(string s)
  353. {
  354. char[] a = s.ToCharArray();
  355. a[0] = char.ToUpper(a[0]);
  356. return new string(a);
  357. }
  358. private Color ChooseColour(bool manager, bool employee, DateTime due)
  359. {
  360. Color color = Color.FromHex("#cb99c9"); //purple / pastel violet
  361. if (manager)
  362. {
  363. if (employee)
  364. {
  365. color = ColorOnDate(due);
  366. }
  367. else
  368. {
  369. color = Color.LightGray;
  370. }
  371. }
  372. else if (employee)
  373. {
  374. color = ColorOnDate(due);
  375. }
  376. return color;
  377. }
  378. private Color ColorOnDate(DateTime due)
  379. {
  380. Color color = Color.FromHex("#77dd77"); //green / pastel green
  381. int result = DateTime.Compare(DateTime.Now, due);
  382. if (result < 0) //relationship = "is earlier than";
  383. {
  384. int result2 = DateTime.Compare(DateTime.Today.AddDays(+7), due);
  385. if (result2 == 0 || result2 > 0)
  386. {
  387. color = Color.FromHex("#fff8dc"); //cornsilk / light yellow
  388. }
  389. }
  390. if (result > 0)//relationship = "is later than";
  391. {
  392. color = Color.FromHex("#f08080"); //light coral / red
  393. }
  394. if (due == DateTime.Today) //relationship = "is the same time as";
  395. {
  396. color = Color.FromHex("#fff8dc"); //cornsilk / light yellow
  397. }
  398. return color;
  399. }
  400. private void ButtonToDo_Clicked(object sender, EventArgs e)
  401. {
  402. currentCategory = 0;
  403. if (!searching)
  404. DisplayList(kanbanSubscriberShells);
  405. else
  406. {
  407. DisplayList(searchList);
  408. }
  409. ChangeButtonColour();
  410. }
  411. private void ButtonCurrent_Clicked(object sender, EventArgs e)
  412. {
  413. currentCategory = 1;
  414. if (!searching)
  415. DisplayList(kanbanSubscriberShells);
  416. else
  417. {
  418. DisplayList(searchList);
  419. }
  420. ChangeButtonColour();
  421. }
  422. private void ButtonWaiting_Clicked(object sender, EventArgs e)
  423. {
  424. currentCategory = 2;
  425. if (!searching)
  426. DisplayList(kanbanSubscriberShells);
  427. else
  428. {
  429. DisplayList(searchList);
  430. }
  431. ChangeButtonColour();
  432. }
  433. private void ChangeButtonColour()
  434. {
  435. switch (currentCategory)
  436. {
  437. case 0:
  438. buttonToDo.BackgroundColor = color;
  439. buttonCurrent.BackgroundColor = Color.Default;
  440. buttonWaiting.BackgroundColor = Color.Default;
  441. break;
  442. case 1:
  443. buttonToDo.BackgroundColor = Color.Default;
  444. buttonCurrent.BackgroundColor = color;
  445. buttonWaiting.BackgroundColor = Color.Default;
  446. break;
  447. case 2:
  448. buttonToDo.BackgroundColor = Color.Default;
  449. buttonCurrent.BackgroundColor = Color.Default;
  450. buttonWaiting.BackgroundColor = color;
  451. break;
  452. }
  453. }
  454. private void ObserverSwitch_Toggled(object sender, EventArgs e)
  455. {
  456. if (firstLoad)
  457. return;
  458. if (observerSwitch.IsToggled)
  459. {
  460. if (App.Current.Properties.ContainsKey("ObserverPreference"))
  461. {
  462. App.Current.Properties["ObserverPreference"] = "True";
  463. }
  464. else
  465. {
  466. App.Current.Properties.Add("ObserverPreference", "True");
  467. }
  468. }
  469. else
  470. {
  471. if (App.Current.Properties.ContainsKey("ObserverPreference"))
  472. {
  473. App.Current.Properties["ObserverPreference"] = "False";
  474. }
  475. else
  476. {
  477. App.Current.Properties.Add("ObserverPreference", "False");
  478. }
  479. }
  480. if (searching) RunSearch();
  481. else
  482. {
  483. RefreshButtons(kanbanSubscriberShells);
  484. DisplayList(kanbanSubscriberShells);
  485. }
  486. }
  487. }
  488. }