use super::name_scroll::{column_width, end_offset, scroll_text}; use crate::models::{SearchEntry, SearchStatus}; use crate::ui::{ HIGHLIGHT_SYMBOL, body_style, dimmed_style, header_style, pane_block, pane_title, row_highlight_style, success_style, warning_style, }; use ratatui::{ Frame, layout::{Constraint, Rect}, widgets::{Cell, HighlightSpacing, Row, Table, TableState}, }; // The pane shares a row with two others, so the fixed columns are as // narrow as their widest word: the query gets the rest. const WIDTHS: [Constraint; 3] = [ Constraint::Length(6), Constraint::Fill(1), Constraint::Length(7), ]; /// Query is the second column. const QUERY_COLUMN: usize = 1; /// The offset that brings the end of a query into view. #[must_use] pub fn query_end_offset(query: &str, area: Rect) -> usize { end_offset(query, area, &WIDTHS, QUERY_COLUMN) } pub fn render_searches_pane( frame: &mut Frame, area: Rect, searches: &[SearchEntry], table_state: &mut TableState, focused: bool, query_offset: usize, ) { let header = Row::new(vec![ Cell::from("Status").style(header_style()), Cell::from("Query").style(header_style()), Cell::from("Results").style(header_style()), ]) .height(1); let query_width = column_width(area, &WIDTHS, QUERY_COLUMN); let rows: Vec = searches .iter() .map(|search| { let status_cell = match &search.status { SearchStatus::Active => { Cell::from("Active").style(warning_style()) } SearchStatus::Completed => { Cell::from("Done").style(success_style()) } }; // What this window has fetched, or what the session says it will // find when it does. A search another window ran has a count long // before this one has pulled the results across. let results_count = if search.results.is_empty() { search.known_files } else { search.results.len() }; // Nothing yet from a search still out: the status column already // says it is looking. let results_text = if results_count == 0 && search.status == SearchStatus::Active { "…".to_string() } else { format!("{results_count}") }; Row::new(vec![ status_cell, Cell::from(scroll_text( &search.query, query_offset, query_width, )) .style(body_style()), Cell::from(results_text).style(dimmed_style()), ]) }) .collect(); let table = Table::new(rows, WIDTHS) .header(header) .row_highlight_style(row_highlight_style()) .highlight_symbol(HIGHLIGHT_SYMBOL) .highlight_spacing(HighlightSpacing::Always) .block(pane_block(focused).title(pane_title("1", "Searches", focused))); frame.render_stateful_widget(table, area, table_state); }