Add items
This commit is contained in:
parent
045e11cd63
commit
b1570a5e11
3 changed files with 304 additions and 87 deletions
260
src/ui.rs
260
src/ui.rs
|
|
@ -6,7 +6,7 @@ use ratatui::{
|
|||
Frame,
|
||||
};
|
||||
|
||||
use crate::{state::{AppState, TimeItem}, app::{App, Screen}};
|
||||
use crate::{state::{AppState, TimeItem}, app::{App, Screen, NewEntryMode}};
|
||||
|
||||
const ACTIVE_COLOR: Color = Color::Green;
|
||||
const INACTIVE_COLOR: Color = Color::Yellow;
|
||||
|
|
@ -16,6 +16,7 @@ pub fn render(frame: &mut Frame, app: &App) {
|
|||
Screen::Main => render_main(frame, app),
|
||||
Screen::Help => render_help(frame, app),
|
||||
Screen::ConfigHelp => render_config_help(frame, app),
|
||||
Screen::NewEntry => render_new_entry(frame, app),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ fn render_main(frame: &mut Frame, app: &App) {
|
|||
render_section(
|
||||
frame,
|
||||
sections[2],
|
||||
"Recent Items",
|
||||
"Ad-Hoc Items",
|
||||
&app.state.recent_items,
|
||||
app.state.current_pane == 2,
|
||||
app.state.selected_indices[2],
|
||||
|
|
@ -100,10 +101,82 @@ fn render_main(frame: &mut Frame, app: &App) {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_new_entry(frame: &mut Frame, app: &App) {
|
||||
let area = centered_rect(60, 6, frame.size());
|
||||
frame.render_widget(Clear, area);
|
||||
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(3),
|
||||
])
|
||||
.split(area);
|
||||
|
||||
// Task name input
|
||||
let task_block = Block::default()
|
||||
.title("Task Name")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(if matches!(app.new_entry_mode, NewEntryMode::Task) {
|
||||
ACTIVE_COLOR
|
||||
} else {
|
||||
Color::White
|
||||
}));
|
||||
|
||||
let task_text = Paragraph::new(app.new_entry_buffer.as_str())
|
||||
.block(task_block);
|
||||
|
||||
frame.render_widget(task_text, chunks[0]);
|
||||
|
||||
// Project input
|
||||
let project_block = Block::default()
|
||||
.title("Project (optional)")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(if matches!(app.new_entry_mode, NewEntryMode::Project) {
|
||||
ACTIVE_COLOR
|
||||
} else {
|
||||
Color::White
|
||||
}));
|
||||
|
||||
let project_text = if !app.config.projects.is_empty() {
|
||||
format!("{} (available: {})",
|
||||
app.new_entry_project,
|
||||
app.config.projects.join(", ")
|
||||
)
|
||||
} else {
|
||||
app.new_entry_project.clone()
|
||||
};
|
||||
|
||||
let project_text = Paragraph::new(project_text)
|
||||
.block(project_block);
|
||||
|
||||
frame.render_widget(project_text, chunks[1]);
|
||||
|
||||
// Render command bar
|
||||
let bar_area = Rect::new(
|
||||
0,
|
||||
frame.size().height - 1,
|
||||
frame.size().width,
|
||||
1,
|
||||
);
|
||||
|
||||
let command_text = match app.new_entry_mode {
|
||||
NewEntryMode::Task => "Enter task name, press Enter to continue",
|
||||
NewEntryMode::Project => "Enter project name (optional), press Enter to save",
|
||||
};
|
||||
|
||||
let command_bar = Paragraph::new(command_text)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.alignment(Alignment::Left);
|
||||
|
||||
frame.render_widget(command_bar, bar_area);
|
||||
}
|
||||
|
||||
fn render_bottom_bar(frame: &mut Frame, area: Rect, app: &App) {
|
||||
if app.config.show_command_hints {
|
||||
let commands = vec![
|
||||
("c", "config"),
|
||||
("n", "new"),
|
||||
("q", "quit"),
|
||||
];
|
||||
|
||||
|
|
@ -167,6 +240,104 @@ fn render_help_command_bar(frame: &mut Frame) {
|
|||
frame.render_widget(command_bar, bar_area);
|
||||
}
|
||||
|
||||
fn render_help(frame: &mut Frame, _app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
frame.render_widget(Clear, area);
|
||||
|
||||
let help_text = vec![
|
||||
"WAT - Watson Time Tracker Interface",
|
||||
"",
|
||||
"This tool helps you track time using Watson with a convenient interface.",
|
||||
"",
|
||||
"The interface is divided into three sections:",
|
||||
"1. Permanent Items: Configured tasks that are always available",
|
||||
"2. Recurring Items: Frequently used tasks that you might return to",
|
||||
"3. Ad-Hoc Items: One-off tasks and quick entries",
|
||||
"",
|
||||
"Navigation:",
|
||||
"- Use j/k or ↑/↓ to move selection up/down",
|
||||
"- Use h/l or ←/→ to switch between panes",
|
||||
"- Use Ctrl+n/Ctrl+p to switch between panes",
|
||||
"- Press Enter to start/stop time tracking",
|
||||
"- Press n to create a new task in the current section",
|
||||
"",
|
||||
"Main Commands:",
|
||||
"j/k, arrows - Navigate",
|
||||
"h/l, arrows - Switch panes",
|
||||
"Enter - Start/stop timer",
|
||||
"Ctrl+e - Edit tasks config",
|
||||
"c - Edit app config",
|
||||
"n - New task",
|
||||
"q - Quit",
|
||||
"? (or ESC) - Exit help",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Help")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
render_help_command_bar(frame);
|
||||
}
|
||||
|
||||
fn render_config_help(frame: &mut Frame, _app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
frame.render_widget(Clear, area);
|
||||
|
||||
let help_text = vec![
|
||||
"WAT Configuration",
|
||||
"",
|
||||
"The configuration file is in YAML format and supports these options:",
|
||||
"",
|
||||
"show_help_hint: true/false",
|
||||
" Controls visibility of the help hint in the bottom bar",
|
||||
"",
|
||||
"show_command_hints: true/false",
|
||||
" Controls visibility of command hints in the bottom bar",
|
||||
"",
|
||||
"projects: [list of strings]",
|
||||
" List of available project names",
|
||||
"",
|
||||
"strict_projects: true/false",
|
||||
" If true, only projects from the projects list are allowed",
|
||||
"",
|
||||
"Example configuration:",
|
||||
"show_help_hint: true",
|
||||
"show_command_hints: true",
|
||||
"projects:",
|
||||
" - project1",
|
||||
" - project2",
|
||||
"strict_projects: false",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Configuration Help")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
render_help_command_bar(frame);
|
||||
}
|
||||
|
||||
fn render_section(
|
||||
frame: &mut Frame,
|
||||
area: Rect,
|
||||
|
|
@ -216,91 +387,6 @@ fn render_section(
|
|||
frame.render_widget(list, area);
|
||||
}
|
||||
|
||||
fn render_help(frame: &mut Frame, _app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
frame.render_widget(Clear, area);
|
||||
|
||||
let help_text = vec![
|
||||
"WAT - Watson Time Tracker Interface",
|
||||
"",
|
||||
"This tool helps you track time using Watson with a convenient interface.",
|
||||
"",
|
||||
"The interface is divided into three sections:",
|
||||
"1. Permanent Items: Configured tasks that are always available",
|
||||
"2. Recurring Items: Frequently used tasks that you might return to",
|
||||
"3. Recent Items: One-off tasks, showing the last 20 used",
|
||||
"",
|
||||
"Navigation:",
|
||||
"- Use j/k or ↑/↓ to move selection up/down",
|
||||
"- Use h/l or ←/→ to switch between panes",
|
||||
"- Press Enter to start/stop time tracking",
|
||||
"",
|
||||
"Main Commands:",
|
||||
"j/k, arrows - Navigate",
|
||||
"h/l, arrows - Switch panes",
|
||||
"Enter - Start/stop timer",
|
||||
"Ctrl+e - Edit tasks config",
|
||||
"c - Edit app config",
|
||||
"q - Quit",
|
||||
"? (or ESC) - Exit help",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Help")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
render_help_command_bar(frame);
|
||||
}
|
||||
|
||||
fn render_config_help(frame: &mut Frame, _app: &App) {
|
||||
let width = frame.size().width.saturating_sub(4).min(60);
|
||||
let area = centered_rect(width, frame.size().height.saturating_sub(2), frame.size());
|
||||
|
||||
frame.render_widget(Clear, area);
|
||||
|
||||
let help_text = vec![
|
||||
"WAT Configuration",
|
||||
"",
|
||||
"The configuration file is in YAML format and supports these options:",
|
||||
"",
|
||||
"show_help_hint: true/false",
|
||||
" Controls visibility of the help hint in the bottom bar",
|
||||
"",
|
||||
"show_command_hints: true/false",
|
||||
" Controls visibility of command hints in the bottom bar",
|
||||
"",
|
||||
"Example configuration:",
|
||||
"show_help_hint: true",
|
||||
"show_command_hints: true",
|
||||
];
|
||||
|
||||
let text = help_text.join("\n");
|
||||
|
||||
let block = Block::default()
|
||||
.title("Configuration Help")
|
||||
.borders(Borders::ALL)
|
||||
.style(Style::default().fg(Color::White));
|
||||
|
||||
let paragraph = Paragraph::new(text)
|
||||
.block(block)
|
||||
.style(Style::default().fg(Color::White))
|
||||
.wrap(ratatui::widgets::Wrap { trim: true });
|
||||
|
||||
frame.render_widget(paragraph, area);
|
||||
render_help_command_bar(frame);
|
||||
}
|
||||
|
||||
fn centered_rect(width: u16, height: u16, r: Rect) -> Rect {
|
||||
let x = (r.width.saturating_sub(width)) / 2;
|
||||
let y = (r.height.saturating_sub(height)) / 2;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue