use crate::components::metadata_line_multi;
use crate::theme::*;
use kanban_core::AppConfig;
use kanban_domain::{Board, Card, Sprint};
use ratatui::{
style::{Color, Style},
text::{Line, Span},
};
pub fn build_title_lines(card: &Card) -> String {
card.title.clone()
}
pub fn build_metadata_lines(
card: &Card,
board: &Board,
sprints: &[Sprint],
app_config: &AppConfig,
) -> Vec<Line<'static>> {
vec![
metadata_line_multi(vec![
("Priority", format!("{:?}", card.priority), normal_text()),
("Status", format!("{:?}", card.status), normal_text()),
(
"Points",
card.points
.map(|p| p.to_string())
.unwrap_or_else(|| "-".to_string()),
normal_text(),
),
]),
if let Some(due_date) = card.due_date {
Line::from(Span::styled(
format!("Due: {}", due_date.format("%Y-%m-%d %H:%M")),
Style::default().fg(Color::Red),
))
} else {
Line::from(Span::styled("No due date", label_text()))
},
Line::from(Span::styled(
format!(
"Branch: {}",
card.branch_name(board, sprints, app_config.effective_default_card_prefix())
),
active_item(),
)),
]
}
pub fn build_description_lines(card: &Card) -> Vec<Line<'static>> {
if let Some(desc_text) = &card.description {
if desc_text.trim().is_empty() {
vec![Line::from(Span::styled("No description", label_text()))]
} else {
crate::markdown_renderer::render_markdown(desc_text)
}
} else {
vec![Line::from(Span::styled("No description", label_text()))]
}
}
pub fn build_sprint_logs_lines(card: &Card) -> Vec<Line<'static>> {
let mut sprint_log_lines = vec![];
let max_visible = 3;
let total_logs = card.sprint_logs.len();
let start_idx = total_logs.saturating_sub(max_visible);
for (display_idx, log) in card.sprint_logs[start_idx..].iter().enumerate() {
let absolute_idx = start_idx + display_idx;
let sprint_name_str = log
.sprint_name
.as_deref()
.unwrap_or(&log.sprint_number.to_string())
.to_string();
let started = log.started_at.format("%m-%d %H:%M").to_string();
let status_str = if let Some(ended) = log.ended_at {
let ended_fmt = ended.format("%m-%d %H:%M").to_string();
format!("{} → {}", started, ended_fmt)
} else {
format!("{} → (current)", started)
};
sprint_log_lines.push(Line::from(vec![
Span::styled(format!("{}. ", absolute_idx + 1), label_text()),
Span::styled(
format!("{} ", sprint_name_str),
Style::default().fg(Color::Cyan),
),
Span::styled(status_str, label_text()),
]));
}
if start_idx > 0 {
sprint_log_lines.insert(
0,
Line::from(Span::styled(
format!("... ({} earlier entries)", start_idx),
label_text(),
)),
);
}
sprint_log_lines
}