metis_docs_tui/app/actions/
navigation.rs1use crate::app::App;
2use crate::error::AppError;
3use crate::models::AppState;
4
5impl App {
6 pub fn next_board(&mut self) {
8 self.ui_state
9 .next_board_with_config(&self.core_state.flight_config);
10 }
11
12 pub fn previous_board(&mut self) {
13 self.ui_state
14 .previous_board_with_config(&self.core_state.flight_config);
15 }
16
17 pub fn jump_to_strategy_board(&mut self) {
18 use crate::app::state::UiState;
19 if UiState::is_board_enabled(
20 crate::models::BoardType::Strategy,
21 &self.core_state.flight_config,
22 ) {
23 self.ui_state.current_board = crate::models::BoardType::Strategy;
24 }
25 }
26
27 pub fn jump_to_initiative_board(&mut self) {
28 use crate::app::state::UiState;
29 if UiState::is_board_enabled(
30 crate::models::BoardType::Initiative,
31 &self.core_state.flight_config,
32 ) {
33 self.ui_state.current_board = crate::models::BoardType::Initiative;
34 }
35 }
36
37 pub fn jump_to_task_board(&mut self) {
38 self.ui_state.current_board = crate::models::BoardType::Task;
40 }
41
42 pub fn jump_to_adr_board(&mut self) {
43 self.ui_state.current_board = crate::models::BoardType::Adr;
45 }
46
47 pub fn jump_to_backlog_board(&mut self) {
48 self.ui_state.current_board = crate::models::BoardType::Backlog;
50 }
51
52 pub fn move_selection_left(&mut self) {
54 let current_board = self.ui_state.current_board;
55 self.selection_state.move_selection_left(current_board);
56 }
57
58 pub fn move_selection_right(&mut self) {
59 let current_board = self.ui_state.current_board;
60 let board = self.ui_state.get_current_board();
61 self.selection_state
62 .move_selection_right(current_board, board.columns.len());
63 }
64
65 pub fn move_selection_up(&mut self) {
66 let current_board = self.ui_state.current_board;
67 self.selection_state.move_selection_up(current_board);
68 }
69
70 pub fn move_selection_down(&mut self) {
71 let current_board = self.ui_state.current_board;
72 let (col_idx, _) = self.selection_state.get_current_selection(current_board);
73 let board = self.ui_state.get_current_board();
74 let max_items = if col_idx < board.columns.len() {
75 board.columns[col_idx].items.len()
76 } else {
77 0
78 };
79 self.selection_state
80 .move_selection_down(current_board, max_items);
81 }
82
83 pub fn view_vision_document(&mut self) {
85 if let Some(workspace_dir) = &self.core_state.workspace_dir {
87 let vision_path = workspace_dir.join("vision.md");
88 if vision_path.exists() {
89 match std::fs::read_to_string(&vision_path) {
91 Ok(_) => {
92 self.ui_state.viewing_ticket =
95 Some((crate::models::BoardType::Strategy, 999, 999));
96
97 self.start_content_editing_for_vision(vision_path);
99 }
100 Err(e) => {
101 self.error_handler.handle_error(AppError::IoError(format!(
102 "Failed to read vision document: {}",
103 e
104 )));
105 }
106 }
107 } else {
108 self.error_handler.handle_error(AppError::DocumentError(
109 "No vision document found. Create one with 'metis create vision' first."
110 .to_string(),
111 ));
112 }
113 }
114 }
115
116 fn start_content_editing_for_vision(&mut self, vision_path: std::path::PathBuf) {
117 self.ui_state.set_app_state(AppState::EditingContent);
118
119 if let Ok(content) = std::fs::read_to_string(&vision_path) {
121 let mut textarea = tui_textarea::TextArea::default();
123 textarea.set_block(
124 ratatui::widgets::Block::default()
125 .borders(ratatui::widgets::Borders::ALL)
126 .title("Vision Document Editor"),
127 );
128
129 for line in content.lines() {
131 textarea.insert_str(line);
132 textarea.insert_newline();
133 }
134
135 self.ui_state.strategy_editor = Some(textarea);
136 self.ui_state.editing_vision_path = Some(vision_path);
138 }
139 }
140}