Formatting
This commit is contained in:
parent
2e2145b2ab
commit
9b4341ccf1
25
src/app.rs
25
src/app.rs
@ -1,13 +1,15 @@
|
|||||||
use std::cmp::min;
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use int_enum::IntEnum;
|
use int_enum::IntEnum;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
#[repr(usize)]
|
#[repr(usize)]
|
||||||
#[derive(Deserialize, Serialize, Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, IntEnum)]
|
#[derive(
|
||||||
|
Deserialize, Serialize, Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, IntEnum,
|
||||||
|
)]
|
||||||
pub enum TaskStatus {
|
pub enum TaskStatus {
|
||||||
Todo = 0,
|
Todo = 0,
|
||||||
InProgress = 1,
|
InProgress = 1,
|
||||||
@ -50,12 +52,12 @@ impl Project {
|
|||||||
pub fn new(name: &str) -> Self {
|
pub fn new(name: &str) -> Self {
|
||||||
Project {
|
Project {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
tasks_per_column: IndexMap::from(
|
tasks_per_column: IndexMap::from([
|
||||||
[(TaskStatus::Done, vec![]),
|
(TaskStatus::Done, vec![]),
|
||||||
(TaskStatus::Todo, vec![]),
|
(TaskStatus::Todo, vec![]),
|
||||||
(TaskStatus::InProgress, vec![]),
|
(TaskStatus::InProgress, vec![]),
|
||||||
(TaskStatus::Ideas, vec![])],
|
(TaskStatus::Ideas, vec![]),
|
||||||
),
|
]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +148,10 @@ impl AppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_next_column(&mut self) {
|
pub fn select_next_column(&mut self) {
|
||||||
self.selected_column = min(self.selected_column + 1, self.project.tasks_per_column.len() - 1)
|
self.selected_column = min(
|
||||||
|
self.selected_column + 1,
|
||||||
|
self.project.tasks_per_column.len() - 1,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_task_previous_column(&mut self) {
|
pub fn move_task_previous_column(&mut self) {
|
||||||
@ -166,7 +171,10 @@ impl AppState {
|
|||||||
pub fn move_task_next_column(&mut self) {
|
pub fn move_task_next_column(&mut self) {
|
||||||
let tasks = self.get_tasks_in_active_column();
|
let tasks = self.get_tasks_in_active_column();
|
||||||
let task_idx = self.selected_task_idx();
|
let task_idx = self.selected_task_idx();
|
||||||
if self.selected_column < self.project.tasks_per_column.len() && tasks.len() > 0 && task_idx < tasks.len() {
|
if self.selected_column < self.project.tasks_per_column.len()
|
||||||
|
&& tasks.len() > 0
|
||||||
|
&& task_idx < tasks.len()
|
||||||
|
{
|
||||||
let task = self.get_tasks_in_active_column_mut().remove(task_idx);
|
let task = self.get_tasks_in_active_column_mut().remove(task_idx);
|
||||||
*self.selected_task_idx_mut() = self.selected_task_idx().saturating_sub(1);
|
*self.selected_task_idx_mut() = self.selected_task_idx().saturating_sub(1);
|
||||||
self.select_next_column();
|
self.select_next_column();
|
||||||
@ -197,4 +205,3 @@ impl AppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
67
src/ui.rs
67
src/ui.rs
@ -1,22 +1,28 @@
|
|||||||
use tui::backend::{Backend};
|
use crate::app::*;
|
||||||
|
use tui::backend::Backend;
|
||||||
use tui::layout::*;
|
use tui::layout::*;
|
||||||
use tui::{Frame};
|
|
||||||
use tui::style::{Color, Modifier, Style};
|
use tui::style::{Color, Modifier, Style};
|
||||||
use tui::text::{Span, Spans};
|
use tui::text::{Span, Spans};
|
||||||
use tui::widgets::*;
|
use tui::widgets::*;
|
||||||
use crate::app::*;
|
use tui::Frame;
|
||||||
|
|
||||||
fn draw_tasks<B: Backend>(f: &mut Frame<B>, area: &Rect, state: &AppState) {
|
fn draw_tasks<B: Backend>(f: &mut Frame<B>, area: &Rect, state: &AppState) {
|
||||||
let columns = Layout::default()
|
let columns = Layout::default()
|
||||||
.direction(Direction::Horizontal)
|
.direction(Direction::Horizontal)
|
||||||
.constraints(
|
.constraints(
|
||||||
vec![Constraint::Percentage(100 / state.project.tasks_per_column.len() as u16);
|
vec![
|
||||||
state.project.tasks_per_column.len()].as_ref()
|
Constraint::Percentage(100 / state.project.tasks_per_column.len() as u16);
|
||||||
|
state.project.tasks_per_column.len()
|
||||||
|
]
|
||||||
|
.as_ref(),
|
||||||
)
|
)
|
||||||
.split(*area);
|
.split(*area);
|
||||||
|
|
||||||
for (i, (status, tasks)) in state.project.tasks_per_column.iter().enumerate() {
|
for (i, (status, tasks)) in state.project.tasks_per_column.iter().enumerate() {
|
||||||
let items: Vec<ListItem> = tasks.iter().enumerate().map(|(j, task)| {
|
let items: Vec<ListItem> = tasks
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(j, task)| {
|
||||||
let mut style = Style::default();
|
let mut style = Style::default();
|
||||||
if i == state.selected_column && j == state.selected_task[state.selected_column] {
|
if i == state.selected_column && j == state.selected_task[state.selected_column] {
|
||||||
style = style.fg(Color::White).add_modifier(Modifier::BOLD);
|
style = style.fg(Color::White).add_modifier(Modifier::BOLD);
|
||||||
@ -26,28 +32,28 @@ fn draw_tasks<B: Backend>(f: &mut Frame<B>, area: &Rect, state: &AppState) {
|
|||||||
let mut s = Span::raw(task.title.as_str());
|
let mut s = Span::raw(task.title.as_str());
|
||||||
s.style = style;
|
s.style = style;
|
||||||
ListItem::new(vec![Spans::from(s)])
|
ListItem::new(vec![Spans::from(s)])
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
let mut style = Style::default();
|
let mut style = Style::default();
|
||||||
if i == state.selected_column { style = style.fg(Color::Green); };
|
if i == state.selected_column {
|
||||||
|
style = style.fg(Color::Green);
|
||||||
|
};
|
||||||
let mut s = Span::raw(format!("{:?}", status));
|
let mut s = Span::raw(format!("{:?}", status));
|
||||||
s.style = Style::default()
|
s.style = Style::default()
|
||||||
.add_modifier(Modifier::BOLD | Modifier::ITALIC | Modifier::UNDERLINED)
|
.add_modifier(Modifier::BOLD | Modifier::ITALIC | Modifier::UNDERLINED)
|
||||||
.fg(Color::White);
|
.fg(Color::White);
|
||||||
let block = Block::default()
|
let block = Block::default().style(style).title(s).borders(Borders::ALL);
|
||||||
.style(style)
|
|
||||||
.title(s)
|
|
||||||
.borders(Borders::ALL);
|
|
||||||
let list = List::new(items).block(block);
|
let list = List::new(items).block(block);
|
||||||
f.render_widget(list, columns[i])
|
f.render_widget(list, columns[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_task_info<B: Backend>(f: &mut Frame<B>, area: &Rect, state: &AppState) {
|
fn draw_task_info<B: Backend>(f: &mut Frame<B>, area: &Rect, state: &AppState) {
|
||||||
let block = Block::default()
|
let block = Block::default().title("TASK INFO").borders(Borders::ALL);
|
||||||
.title("TASK INFO")
|
|
||||||
.borders(Borders::ALL);
|
|
||||||
if let Some(task) = state.get_selected_task() {
|
if let Some(task) = state.get_selected_task() {
|
||||||
let p = Paragraph::new(task.description.as_str()).block(block).wrap(Wrap { trim: true });
|
let p = Paragraph::new(task.description.as_str())
|
||||||
|
.block(block)
|
||||||
|
.wrap(Wrap { trim: true });
|
||||||
f.render_widget(p, *area);
|
f.render_widget(p, *area);
|
||||||
} else {
|
} else {
|
||||||
let p = Paragraph::new("No tasks for this column").block(block);
|
let p = Paragraph::new("No tasks for this column").block(block);
|
||||||
@ -86,12 +92,12 @@ pub fn draw_new_task_popup<B: Backend>(f: &mut Frame<B>, state: &mut AppState) {
|
|||||||
match &state.popup_text {
|
match &state.popup_text {
|
||||||
None => {}
|
None => {}
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
let block = Block::default().title("Add Task")
|
let block = Block::default()
|
||||||
|
.title("Add Task")
|
||||||
.title_alignment(Alignment::Center)
|
.title_alignment(Alignment::Center)
|
||||||
.borders(Borders::ALL);
|
.borders(Borders::ALL);
|
||||||
let block_inner = block.inner(area);
|
let block_inner = block.inner(area);
|
||||||
let main = Paragraph::new(s.as_ref())
|
let main = Paragraph::new(s.as_ref()).block(block);
|
||||||
.block(block);
|
|
||||||
let layout = Layout::default()
|
let layout = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.constraints(
|
.constraints(
|
||||||
@ -99,8 +105,10 @@ pub fn draw_new_task_popup<B: Backend>(f: &mut Frame<B>, state: &mut AppState) {
|
|||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
Constraint::Max(100),
|
Constraint::Max(100),
|
||||||
Constraint::Length(2),
|
Constraint::Length(2),
|
||||||
].as_ref()
|
]
|
||||||
).split(block_inner);
|
.as_ref(),
|
||||||
|
)
|
||||||
|
.split(block_inner);
|
||||||
let b1 = Block::default().title("Title").borders(Borders::ALL);
|
let b1 = Block::default().title("Title").borders(Borders::ALL);
|
||||||
let title = Paragraph::new("Hello I am text")
|
let title = Paragraph::new("Hello I am text")
|
||||||
// .style(Style::default().fg(Color::Yellow))
|
// .style(Style::default().fg(Color::Yellow))
|
||||||
@ -110,8 +118,7 @@ pub fn draw_new_task_popup<B: Backend>(f: &mut Frame<B>, state: &mut AppState) {
|
|||||||
// .style(Style::default().fg(Color::Yellow))
|
// .style(Style::default().fg(Color::Yellow))
|
||||||
.block(b2);
|
.block(b2);
|
||||||
let b3 = Block::default().title("Keys").borders(Borders::TOP);
|
let b3 = Block::default().title("Keys").borders(Borders::TOP);
|
||||||
let footer = Paragraph::new("p : Cancel")
|
let footer = Paragraph::new("p : Cancel").block(b3);
|
||||||
.block(b3);
|
|
||||||
f.render_widget(main, area);
|
f.render_widget(main, area);
|
||||||
f.render_widget(title, layout[0]);
|
f.render_widget(title, layout[0]);
|
||||||
f.render_widget(description, layout[1]);
|
f.render_widget(description, layout[1]);
|
||||||
@ -129,21 +136,19 @@ pub fn draw<B: Backend>(f: &mut Frame<B>, state: &mut AppState) {
|
|||||||
Constraint::Percentage(65),
|
Constraint::Percentage(65),
|
||||||
Constraint::Percentage(20),
|
Constraint::Percentage(20),
|
||||||
Constraint::Length(3),
|
Constraint::Length(3),
|
||||||
].as_ref()
|
]
|
||||||
).split(f.size());
|
.as_ref(),
|
||||||
|
)
|
||||||
|
.split(f.size());
|
||||||
|
|
||||||
let block = Block::default()
|
let block = Block::default().title("KANBAN BOARD").borders(Borders::ALL);
|
||||||
.title("KANBAN BOARD")
|
|
||||||
.borders(Borders::ALL);
|
|
||||||
f.render_widget(block, main_layout[0]);
|
f.render_widget(block, main_layout[0]);
|
||||||
|
|
||||||
draw_tasks(f, &main_layout[1], &state);
|
draw_tasks(f, &main_layout[1], &state);
|
||||||
|
|
||||||
draw_task_info(f, &main_layout[2], &state);
|
draw_task_info(f, &main_layout[2], &state);
|
||||||
|
|
||||||
let block = Block::default()
|
let block = Block::default().title("KEYBINDINGS").borders(Borders::TOP);
|
||||||
.title("KEYBINDINGS")
|
|
||||||
.borders(Borders::TOP);
|
|
||||||
|
|
||||||
let foot_txt =
|
let foot_txt =
|
||||||
Paragraph::new("q : Quit | ⏪🔽🔼⏩ or hjkl : Navigation | < > or H L : Shift task left/right | = - or J K : Shift task up/down")
|
Paragraph::new("q : Quit | ⏪🔽🔼⏩ or hjkl : Navigation | < > or H L : Shift task left/right | = - or J K : Shift task up/down")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user