view.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. use std::{fmt::Write, str::FromStr};
  2. use prettytable::{
  3. cell,
  4. format::{consts::FORMAT_NO_COLSEP, FormatBuilder, LinePosition, LineSeparator},
  5. row, table, Cell, Row, Table,
  6. };
  7. use darkfi::{
  8. util::time::{timestamp_to_date, DateFormat},
  9. Result,
  10. };
  11. use crate::{
  12. filter::apply_filter,
  13. primitives::{Comment, State, TaskInfo},
  14. TaskEvent,
  15. };
  16. pub fn print_task_list(tasks: Vec<TaskInfo>, filters: Vec<String>) -> Result<()> {
  17. let mut tasks = tasks;
  18. let mut table = Table::new();
  19. table.set_format(
  20. FormatBuilder::new()
  21. .padding(1, 1)
  22. .separators(&[LinePosition::Title], LineSeparator::new('-', ' ', ' ', ' '))
  23. .build(),
  24. );
  25. table.set_titles(row!["ID", "Title", "Project", "Assigned", "Due", "Rank"]);
  26. for filter in filters {
  27. apply_filter(&mut tasks, &filter);
  28. }
  29. tasks.sort_by(|a, b| b.rank.partial_cmp(&a.rank).unwrap());
  30. let mut min_rank = 0.0;
  31. let mut max_rank = 0.0;
  32. if let Some(first) = tasks.first() {
  33. max_rank = first.rank;
  34. }
  35. if let Some(last) = tasks.last() {
  36. min_rank = last.rank;
  37. }
  38. let workspace = if tasks.first().is_some() {
  39. format!("Workspace: {}", tasks.first().unwrap().workspace.clone())
  40. } else {
  41. format!("Workspace: ")
  42. };
  43. for task in tasks {
  44. let state = task.events.last().unwrap_or(&TaskEvent::default()).action.clone();
  45. let state = State::from_str(&state)?;
  46. let (max_style, min_style, mid_style, gen_style) = if state.is_start() {
  47. ("bFg", "Fc", "Fg", "Fg")
  48. } else if state.is_pause() {
  49. ("iFYBd", "iFYBd", "iFYBd", "iFYBd")
  50. } else {
  51. ("", "", "", "")
  52. };
  53. let rank = task.rank.to_string();
  54. table.add_row(Row::new(vec![
  55. Cell::new(&task.id.to_string()).style_spec(gen_style),
  56. Cell::new(&task.title).style_spec(gen_style),
  57. Cell::new(&task.project.join(", ")).style_spec(gen_style),
  58. Cell::new(&task.assign.join(", ")).style_spec(gen_style),
  59. Cell::new(&timestamp_to_date(task.due.unwrap_or(0), DateFormat::Date))
  60. .style_spec(gen_style),
  61. if task.rank == max_rank {
  62. Cell::new(&rank).style_spec(max_style)
  63. } else if task.rank == min_rank {
  64. Cell::new(&rank).style_spec(min_style)
  65. } else {
  66. Cell::new(&rank).style_spec(mid_style)
  67. },
  68. ]));
  69. }
  70. let mut ws_table = table!([Fb => workspace]);
  71. ws_table.set_format(
  72. FormatBuilder::new()
  73. .padding(1, 1)
  74. .separators(&[LinePosition::Bottom], LineSeparator::new('-', ' ', ' ', ' '))
  75. .build(),
  76. );
  77. ws_table.printstd();
  78. table.printstd();
  79. Ok(())
  80. }
  81. pub fn print_task_info(taskinfo: TaskInfo) -> Result<()> {
  82. let current_state = &taskinfo.events.last().unwrap_or(&TaskEvent::default()).action.clone();
  83. let due = timestamp_to_date(taskinfo.due.unwrap_or(0), DateFormat::Date);
  84. let created_at = timestamp_to_date(taskinfo.created_at, DateFormat::DateTime);
  85. let mut table = table!(
  86. [Bd => "ref_id", &taskinfo.ref_id],
  87. ["workspace", &taskinfo.workspace],
  88. [Bd =>"id", &taskinfo.id.to_string()],
  89. ["owner", &taskinfo.owner],
  90. [Bd =>"title", &taskinfo.title],
  91. ["desc", &taskinfo.desc.to_string()],
  92. [Bd =>"assign", taskinfo.assign.join(", ")],
  93. ["project", taskinfo.project.join(", ")],
  94. [Bd =>"due", due],
  95. ["rank", &taskinfo.rank.to_string()],
  96. [Bd =>"created_at", created_at],
  97. ["current_state", current_state]);
  98. table.set_format(
  99. FormatBuilder::new()
  100. .padding(1, 1)
  101. .separators(&[LinePosition::Title], LineSeparator::new('-', ' ', ' ', ' '))
  102. .build(),
  103. );
  104. table.set_titles(row!["Name", "Value"]);
  105. table.printstd();
  106. let mut event_table = table!(["events", &events_as_string(taskinfo.events)]);
  107. event_table.set_format(*FORMAT_NO_COLSEP);
  108. event_table.printstd();
  109. Ok(())
  110. }
  111. pub fn comments_as_string(comments: Vec<Comment>) -> String {
  112. let mut comments_str = String::new();
  113. for comment in comments {
  114. writeln!(comments_str, "{}", comment).unwrap();
  115. }
  116. comments_str.pop();
  117. comments_str
  118. }
  119. pub fn events_as_string(events: Vec<TaskEvent>) -> String {
  120. let mut events_str = String::new();
  121. for event in events {
  122. writeln!(events_str, "State changed to {} at {}", event.action, event.timestamp).unwrap();
  123. }
  124. events_str
  125. }