use crate::action::view;
use ratatui::{
prelude::*,
widgets::{Block, BorderType, Borders, Tabs},
};
#[derive(Default, Debug, Clone, PartialEq, Eq, Hash)]
pub enum View {
#[default]
All,
Remote,
Local,
Prompt,
}
impl From<View> for usize {
fn from(v: View) -> usize {
match v {
View::All => 0,
View::Remote => 1,
View::Local => 2,
View::Prompt => 0, }
}
}
impl From<view::View> for View {
fn from(k: view::View) -> View {
match k {
view::View::A => View::All,
view::View::R => View::Remote,
view::View::L => View::Local,
view::View::Prompt => View::Prompt, }
}
}
#[derive(Debug)]
pub struct Jobs<'a> {
block: Block<'a>,
view: View,
}
impl<'a> Jobs<'a> {
pub fn new() -> Jobs<'a> {
Jobs {
block: Block::default()
.title("Jobs")
.title_alignment(Alignment::Left)
.borders(Borders::ALL)
.border_style(Style::default())
.border_type(BorderType::Rounded),
view: View::default(),
}
}
fn tab_bar_widget(&self) -> Tabs<'a> {
let job_tab_titles = match self.view {
View::All => vec!["All", "Remote", "Local"],
View::Remote => vec!["Remote", "Local", "All"],
View::Local => vec!["Local", "All", "Remote"],
View::Prompt => unreachable!(), };
Tabs::new(
job_tab_titles
.iter()
.map(|t| {
let (first, rest) = t.split_at(1);
Line::from(vec![first.white(), rest.gray()])
})
.collect(),
)
.block(Block::default().borders(Borders::NONE))
.select(0)
.style(Style::default())
.highlight_style(Style::default().bold())
}
fn layers(area: Rect) -> (Rect, Rect) {
let jobs_bar = Layout::default()
.direction(Direction::Vertical)
.constraints(vec![Constraint::Max(3), Constraint::Min(1)])
.split(area.inner(&Margin {
horizontal: 1,
vertical: 1,
}));
(area, jobs_bar[0])
}
pub fn set_view(&mut self, k: view::View) {
self.view = View::from(k);
}
pub fn render(&mut self, area: Rect, f: &mut Frame<'_>) {
let (main_area, tab_bar_area) = Self::layers(area);
let tab_bar = self.tab_bar_widget();
f.render_widget(self.block.clone(), main_area);
f.render_widget(tab_bar, tab_bar_area);
}
}