mirror of
https://github.com/Noratrieb/service-manager.git
synced 2026-01-16 09:25:05 +01:00
make service
This commit is contained in:
parent
48304dce33
commit
3722a458eb
3 changed files with 57 additions and 24 deletions
|
|
@ -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(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/model.rs
19
src/model.rs
|
|
@ -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),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
41
src/view.rs
41
src/view.rs
|
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue