Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kdheepak committed Sep 27, 2023
1 parent ff6c0e6 commit f6c2033
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 29 deletions.
67 changes: 45 additions & 22 deletions src/components/task_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use task_hookrs::{import::import, task::Task, uda::UDAValue};
use tokio::sync::mpsc::UnboundedSender;
use tui_input::backend::crossterm::EventHandler;
use unicode_truncate::UnicodeTruncateStr;
use unicode_width::UnicodeWidthStr;
use uuid::Uuid;

use super::{Component, Frame};
Expand Down Expand Up @@ -120,8 +121,6 @@ impl TaskReport {

pub fn generate_rows(&mut self) -> Result<()> {
self.rows = vec![];

// get all tasks as their string representation
for task in self.tasks.iter() {
if self.columns.is_empty() {
break;
Expand Down Expand Up @@ -467,6 +466,44 @@ impl TaskReport {
self.state.select(Some(self.current_selection));
log::info!("{:?}", self.state);
}

pub fn calculate_widths(&self, maximum_available_width: u16) -> Vec<usize> {
// naive implementation of calculate widths
let mut widths = self.labels.iter().map(String::len).collect::<Vec<usize>>();
for i in 0..self.labels.len() {
let max_width = self.rows.iter().map(|row| row[i].len()).max().unwrap_or(0);
if max_width == 0 {
widths[i] = 0
} else {
widths[i] = widths[i].max(max_width);
}
}
for (i, header) in self.labels.iter().enumerate() {
if header == "Description" || header == "Definition" {
// always give description or definition the most room to breath
widths[i] = maximum_available_width as usize;
break;
}
}
for (i, header) in self.labels.iter().enumerate() {
if i == 0 {
// always give ID a couple of extra for indicator
widths[i] += self.config.task_report.selection_indicator.as_str().width();
// if let TableMode::MultipleSelection = self.task_table_state.mode() {
// widths[i] += 2
// };
}
}
// now start trimming
while (widths.iter().sum::<usize>() as u16) >= maximum_available_width - (self.labels.len()) as u16 {
let index = widths.iter().position(|i| i == widths.iter().max().unwrap_or(&0)).unwrap_or_default();
if widths[index] == 1 {
break;
}
widths[index] -= 1;
}
widths
}
}

impl Component for TaskReport {
Expand Down Expand Up @@ -495,34 +532,20 @@ impl Component for TaskReport {
}

fn draw(&mut self, f: &mut Frame<'_>, rect: Rect) -> Result<()> {
let column_spacing = 1;
if self.rows.len() == 0 {
f.render_widget(Paragraph::new("No data found").block(Block::new().borders(Borders::all())), rect);
return Ok(());
}
let mut total_fixed_widths = 0;
let mut constraints = Vec::with_capacity(self.rows[0].len());

for i in 0..self.rows[0].len() {
if self.columns[i] == "description" {
constraints.push(Constraint::Min(0)); // temporary, will update later
} else {
let max_width = self.rows.iter().map(|row| row[i].len() as u16).max().unwrap_or(0);
total_fixed_widths += max_width + 2; // adding 2 for padding
constraints.push(Constraint::Length(max_width + 2));
}
}

if let Some(pos) = self.columns.iter().position(|x| x == "description") {
let description_width = rect.width.saturating_sub(total_fixed_widths).saturating_sub(4);
constraints[pos] = Constraint::Length(description_width);
}
let widths = self.calculate_widths(rect.width);
let constraints: Vec<Constraint> = widths.iter().map(|i| Constraint::Min(*i as u16)).collect();
let rows = self.rows.iter().map(|row| Row::new(row.clone()));
let table = Table::new(rows)
.header(Row::new(self.columns.clone()))
.header(Row::new(self.labels.clone()))
.widths(&constraints)
.block(Block::new().borders(Borders::ALL))
.highlight_symbol(&self.config.task_report.selection_indicator)
.highlight_spacing(HighlightSpacing::Always);
.highlight_spacing(HighlightSpacing::Always)
.column_spacing(column_spacing);
f.render_stateful_widget(table, rect, &mut self.state);

Ok(())
Expand Down
36 changes: 29 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use derive_deref::{Deref, DerefMut};
use ratatui::style::{Color, Modifier, Style};
use serde::de::{self, Deserialize, Deserializer, MapAccess, Visitor};
use serde_derive::Deserialize;
use serde_derive::{Deserialize, Serialize};
use serde_json::Value as JsonValue;

use crate::{action::Action, app::Mode};

const CONFIG: &str = include_str!("../.config/config.json5");

#[derive(Clone, Debug, Deserialize, Default)]
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
pub struct TaskReportConfig {
#[serde(default)]
pub looping: bool,
Expand All @@ -22,11 +23,33 @@ pub struct TaskReportConfig {

impl Into<Value> for TaskReportConfig {
fn into(self) -> Value {
let mut map = HashMap::new();
map.insert("looping".to_string(), Value::from(self.looping));
map.insert("selection_indicator".to_string(), Value::from(self.selection_indicator));
let json_value = serde_json::to_value(self).unwrap();
_convert_json_to_config(json_value)
}
}

Value::from(map)
fn _convert_json_to_config(json_value: serde_json::Value) -> config::Value {
match json_value {
JsonValue::Null => config::Value::new(None, config::ValueKind::Nil),
JsonValue::Bool(b) => config::Value::from(b),
JsonValue::Number(n) => {
if let Some(i) = n.as_i64() {
config::Value::from(i)
} else if let Some(f) = n.as_f64() {
config::Value::from(f)
} else {
unreachable!()
}
},
JsonValue::String(s) => config::Value::from(s),
JsonValue::Array(arr) => {
let cv_arr: Vec<_> = arr.into_iter().map(_convert_json_to_config).collect();
config::Value::new(None, config::ValueKind::Array(cv_arr))
},
JsonValue::Object(map) => {
let cv_map: HashMap<_, _> = map.into_iter().map(|(k, v)| (k, _convert_json_to_config(v))).collect();
config::Value::new(None, config::ValueKind::Table(cv_map))
},
}
}

Expand Down Expand Up @@ -60,7 +83,6 @@ impl Config {
.set_default("_data_dir", data_dir.to_str().unwrap())?
.set_default("_config_dir", config_dir.to_str().unwrap())?;

// List of potential configuration files provided by the user
let config_files = [
("config.json5", config::FileFormat::Json5),
("config.json", config::FileFormat::Json),
Expand Down

0 comments on commit f6c2033

Please sign in to comment.