kanban-tui 0.9.0

Terminal user interface for the kanban project management tool
Documentation
use super::{App, BoardField, CardField};
use crate::editor::edit_in_external_editor;
use crate::events::EventHandler;
use ratatui::{backend::CrosstermBackend, Terminal};
use std::io;

impl App {
    pub fn edit_board_field(
        &mut self,
        terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
        event_handler: &EventHandler,
        field: BoardField,
    ) -> io::Result<()> {
        if let Some(board_id) = self.board_list.get_selected_board_id() {
            let board = self
                .model
                .board_by_id_state(board_id)
                .loaded()
                .copied()
                .cloned();
            if let Some(board) = board {
                let temp_dir = std::env::temp_dir();
                let (temp_file, current_content) = match field {
                    BoardField::Name => {
                        let temp_file = temp_dir.join(format!("kanban-board-{}-name.md", board.id));
                        (temp_file, board.name.clone())
                    }
                    BoardField::Description => {
                        let temp_file =
                            temp_dir.join(format!("kanban-board-{}-description.md", board.id));
                        let content = board.description.as_deref().unwrap_or("").to_string();
                        (temp_file, content)
                    }
                };

                let board_id = board.id;
                if let Some(new_content) =
                    edit_in_external_editor(terminal, event_handler, temp_file, &current_content)?
                {
                    let updates = match field {
                        BoardField::Name => {
                            if new_content.trim().is_empty() {
                                None
                            } else {
                                Some(kanban_domain::BoardUpdate {
                                    name: Some(new_content.trim().to_string()),
                                    ..Default::default()
                                })
                            }
                        }
                        BoardField::Description => {
                            let desc = if new_content.trim().is_empty() {
                                kanban_domain::FieldUpdate::Clear
                            } else {
                                kanban_domain::FieldUpdate::Set(new_content)
                            };
                            Some(kanban_domain::BoardUpdate {
                                description: desc,
                                ..Default::default()
                            })
                        }
                    };
                    if let Some(updates) = updates {
                        let cmd = kanban_domain::commands::Command::Board(
                            kanban_domain::commands::BoardCommand::Update(
                                kanban_domain::commands::UpdateBoard { board_id, updates },
                            ),
                        );
                        if let Err(e) = self.execute_command(cmd) {
                            tracing::error!("Failed to update board: {}", e);
                        }
                        self.reload_model();
                    }
                }
            }
        }
        Ok(())
    }

    pub fn edit_card_field(
        &mut self,
        terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
        event_handler: &EventHandler,
        field: CardField,
    ) -> io::Result<()> {
        if let Some(active_id) = self.selection.active_card_id {
            if let Some(card) = self.model.card_by_id_state(active_id).loaded().copied() {
                let temp_dir = std::env::temp_dir();
                let (temp_file, current_content) = match field {
                    CardField::Title => {
                        let temp_file = temp_dir.join(format!("kanban-card-{}-title.md", card.id));
                        (temp_file, card.title.clone())
                    }
                    CardField::Description => {
                        let temp_file =
                            temp_dir.join(format!("kanban-card-{}-description.md", card.id));
                        let content = card.description.as_deref().unwrap_or("").to_string();
                        (temp_file, content)
                    }
                };

                let card_id = card.id;
                if let Some(new_content) =
                    edit_in_external_editor(terminal, event_handler, temp_file, &current_content)?
                {
                    let updates = match field {
                        CardField::Title => {
                            if new_content.trim().is_empty() {
                                None
                            } else {
                                Some(kanban_domain::CardUpdate {
                                    title: Some(new_content.trim().to_string()),
                                    ..Default::default()
                                })
                            }
                        }
                        CardField::Description => {
                            let desc = if new_content.trim().is_empty() {
                                kanban_domain::FieldUpdate::Clear
                            } else {
                                kanban_domain::FieldUpdate::Set(new_content)
                            };
                            Some(kanban_domain::CardUpdate {
                                description: desc,
                                ..Default::default()
                            })
                        }
                    };
                    if let Some(updates) = updates {
                        let cmd = kanban_domain::commands::Command::Card(
                            kanban_domain::commands::CardCommand::Update(
                                kanban_domain::commands::UpdateCard { card_id, updates },
                            ),
                        );
                        if let Err(e) = self.execute_command(cmd) {
                            tracing::error!("Failed to update card: {}", e);
                        }
                        self.reload_model();
                    }
                }
            }
        }
        Ok(())
    }
}