make service

This commit is contained in:
nora 2021-12-17 18:20:15 +01:00
parent 48304dce33
commit 3722a458eb
3 changed files with 57 additions and 24 deletions

View file

@ -1,4 +1,4 @@
use crate::model::{AppState, AppStateFullView}; use crate::model::{AppState, AppStateFullView, Service, ServiceStatus};
use crate::{view, App}; use crate::{view, App};
use crossterm::event; use crossterm::event;
use crossterm::event::{Event, KeyCode}; use crossterm::event::{Event, KeyCode};
@ -33,9 +33,18 @@ impl App {
table: AppState { table: AppState {
table_state: TableState::default(), table_state: TableState::default(),
items: vec![ items: vec![
vec!["backend".to_string(), "running".to_string()], Service {
vec!["frontend".to_string(), "exited (0)".to_string()], name: "backend".to_string(),
vec!["database".to_string(), "failed (1)".to_string()], status: ServiceStatus::Running,
},
Service {
name: "frontend".to_string(),
status: ServiceStatus::Exited,
},
Service {
name: "database".to_string(),
status: ServiceStatus::Failed(1),
},
], ],
}, },
selected: None, selected: None,
@ -49,9 +58,7 @@ impl App {
fn select_service(&mut self) { fn select_service(&mut self) {
if self.is_table() { if self.is_table() {
if let Some(selected) = self.table.table_state.selected() { if let Some(selected) = self.table.table_state.selected() {
self.selected = Some(AppStateFullView { self.selected = Some(AppStateFullView { index: selected });
name: self.table.items[selected][0].to_string(),
});
} }
} }
} }

View file

@ -3,16 +3,29 @@ use tui::widgets::TableState;
#[derive(Debug)] #[derive(Debug)]
pub struct App { pub struct App {
pub table: AppState, pub table: AppState,
pub selected: Option<AppStateFullView> pub selected: Option<AppStateFullView>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct AppState { pub struct AppState {
pub table_state: TableState, pub table_state: TableState,
pub items: Vec<Vec<String>>, pub items: Vec<Service>,
} }
#[derive(Debug)] #[derive(Debug)]
pub struct AppStateFullView { pub struct AppStateFullView {
pub name: String, pub index: usize,
}
#[derive(Debug)]
pub struct Service {
pub name: String,
pub status: ServiceStatus,
}
#[derive(Debug)]
pub enum ServiceStatus {
Running,
Exited,
Failed(u8),
} }

View file

@ -1,3 +1,4 @@
use std::fmt::{Display, Formatter};
use tui::backend::Backend; use tui::backend::Backend;
use tui::layout::{Constraint, Layout, Rect}; use tui::layout::{Constraint, Layout, Rect};
use tui::style::{Color, Modifier, Style}; use tui::style::{Color, Modifier, Style};
@ -5,7 +6,7 @@ use tui::text::Spans;
use tui::widgets::{Block, Borders, Cell, Paragraph, Row, Table}; use tui::widgets::{Block, Borders, Cell, Paragraph, Row, Table};
use tui::Frame; use tui::Frame;
use crate::model::{AppState, AppStateFullView}; use crate::model::{AppState, AppStateFullView, ServiceStatus};
use crate::App; use crate::App;
pub fn render_ui<B: Backend>(f: &mut Frame<B>, app: &mut App) { pub fn render_ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
@ -23,10 +24,14 @@ pub fn render_ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
None => { None => {
render_table(f, &mut app.table, chunks[0]); render_table(f, &mut app.table, chunks[0]);
} }
Some(AppStateFullView { ref name }) => f.render_widget( Some(AppStateFullView { index }) => {
Block::default().borders(Borders::ALL).title(name.as_ref()), let name = &app.table.items[index].name;
chunks[0],
), f.render_widget(
Block::default().borders(Borders::ALL).title(name.as_ref()),
chunks[0],
)
}
} }
if let Some(footer_chunk) = chunks.get(1) { if let Some(footer_chunk) = chunks.get(1) {
@ -46,14 +51,12 @@ fn render_table<B: Backend>(f: &mut Frame<B>, state: &mut AppState, area: Rect)
.height(1) .height(1)
.bottom_margin(1); .bottom_margin(1);
let rows = state.items.iter().map(|item| { let rows = state.items.iter().map(|service| {
let height = item let height = service.name.chars().filter(|c| *c == '\n').count() + 1;
.iter() let cells = [
.map(|content| content.chars().filter(|c| *c == '\n').count()) Cell::from(service.name.as_ref()),
.max() Cell::from(service.status.to_string()),
.unwrap_or(0) ];
+ 1;
let cells = item.iter().map(|c| Cell::from(c.as_ref()));
Row::new(cells).height(height as u16).bottom_margin(1) Row::new(cells).height(height as u16).bottom_margin(1)
}); });
@ -66,7 +69,7 @@ fn render_table<B: Backend>(f: &mut Frame<B>, state: &mut AppState, area: Rect)
f.render_stateful_widget(t, area, &mut state.table_state); f.render_stateful_widget(t, area, &mut state.table_state);
} }
pub fn render_help_footer<B: Backend>(f: &mut Frame<B>, app: &App, area: Rect) { fn render_help_footer<B: Backend>(f: &mut Frame<B>, app: &App, area: Rect) {
let block = Block::default().title("help").borders(Borders::ALL); let block = Block::default().title("help").borders(Borders::ALL);
let paragraph = Paragraph::new(if app.is_table() { let paragraph = Paragraph::new(if app.is_table() {
@ -78,3 +81,13 @@ pub fn render_help_footer<B: Backend>(f: &mut Frame<B>, app: &App, area: Rect) {
f.render_widget(paragraph, area); f.render_widget(paragraph, area);
} }
impl Display for ServiceStatus {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
ServiceStatus::Running => f.write_str("running"),
ServiceStatus::Exited => f.write_str("exited (0)"),
ServiceStatus::Failed(code) => write!(f, "failed ({})", code),
}
}
}