use crate::query_pack::PackQuery;
use tui_textarea::TextArea;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EditorMode {
Normal, Insert, Visual, }
#[derive(Debug, Clone)]
pub struct PackContext {
pub pack_name: String,
pub pack_path: String,
pub queries: Vec<PackQuery>,
pub current_index: usize,
}
impl PackContext {
pub fn next_query(&mut self) -> Option<&PackQuery> {
if self.queries.is_empty() {
return None;
}
self.current_index = (self.current_index + 1) % self.queries.len();
Some(&self.queries[self.current_index])
}
pub fn prev_query(&mut self) -> Option<&PackQuery> {
if self.queries.is_empty() {
return None;
}
if self.current_index == 0 {
self.current_index = self.queries.len() - 1;
} else {
self.current_index -= 1;
}
Some(&self.queries[self.current_index])
}
#[allow(dead_code)]
pub fn current_query(&self) -> Option<&PackQuery> {
self.queries.get(self.current_index)
}
pub fn display_string(&self) -> String {
format!(
"{} ({}/{})",
self.pack_name,
self.current_index + 1,
self.queries.len()
)
}
}
#[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>,
pub pack_context: Option<PackContext>,
}
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,
pack_context: 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
}
}