use tui_textarea::TextArea;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EditorMode {
Normal, Insert, Visual, }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LoadPanelSort {
Status, Alphabetical, Chronological, }
impl LoadPanelSort {
pub fn next(self) -> Self {
match self {
LoadPanelSort::Status => LoadPanelSort::Alphabetical,
LoadPanelSort::Alphabetical => LoadPanelSort::Chronological,
LoadPanelSort::Chronological => LoadPanelSort::Status,
}
}
pub fn as_str(self) -> &'static str {
match self {
LoadPanelSort::Status => "Status",
LoadPanelSort::Alphabetical => "Name",
LoadPanelSort::Chronological => "Time",
}
}
}
#[derive(Debug, Clone)]
pub struct LoadPanelState {
pub selected: usize,
pub sort: LoadPanelSort,
pub inverted: bool,
pub original_query: String,
pub sorted_indices: Vec<usize>,
}
pub struct QueryModel {
pub textarea: TextArea<'static>,
pub mode: EditorMode,
pub job_name_input: Option<String>,
pub load_panel: Option<LoadPanelState>,
}
impl QueryModel {
pub fn new() -> Self {
let mut textarea = TextArea::default();
textarea.set_cursor_line_style(ratatui::style::Style::default());
textarea.set_line_number_style(
ratatui::style::Style::default().fg(ratatui::style::Color::DarkGray),
);
Self {
textarea,
mode: EditorMode::Normal,
job_name_input: None,
load_panel: None,
}
}
pub fn get_text(&self) -> String {
self.textarea.lines().join("\n")
}
pub fn get_preview(&self, max_len: usize) -> String {
self.get_text().chars().take(max_len).collect()
}
pub fn clear(&mut self) {
self.textarea = TextArea::default();
self.textarea
.set_cursor_line_style(ratatui::style::Style::default());
self.textarea.set_line_number_style(
ratatui::style::Style::default().fg(ratatui::style::Color::DarkGray),
);
}
pub fn set_text(&mut self, text: String) {
let lines: Vec<String> = text.lines().map(|s| s.to_string()).collect();
self.textarea = TextArea::from(lines);
self.textarea
.set_cursor_line_style(ratatui::style::Style::default());
self.textarea.set_line_number_style(
ratatui::style::Style::default().fg(ratatui::style::Color::DarkGray),
);
}
}
impl Default for QueryModel {
fn default() -> Self {
Self::new()
}
}
impl LoadPanelState {
pub fn compute_sorted_indices(&self, jobs: &[crate::tui::model::jobs::JobState]) -> Vec<usize> {
use crate::tui::model::jobs::JobStatus;
let mut indices: Vec<usize> = (0..jobs.len()).collect();
match self.sort {
LoadPanelSort::Status => {
indices.sort_by_key(|&idx| match jobs[idx].status {
JobStatus::Running => 0,
JobStatus::Queued => 1,
JobStatus::Failed => 2,
JobStatus::Completed => 3,
});
}
LoadPanelSort::Alphabetical => {
indices.sort_by(|&a, &b| jobs[a].workspace_name.cmp(&jobs[b].workspace_name));
}
LoadPanelSort::Chronological => {
}
}
if self.inverted {
indices.reverse();
}
indices
}
}