Refactored tables and loading blocks to use the new dedicated widgets for Tables and Loading blocks

This commit is contained in:
2024-02-10 19:23:19 -07:00
parent 68de986c48
commit 51b789fd0f
19 changed files with 1174 additions and 1150 deletions
+33
View File
@@ -0,0 +1,33 @@
use crate::ui::styles::ManagarrStyle;
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::prelude::Text;
use ratatui::widgets::{Block, Paragraph, Widget};
pub struct LoadingBlock<'a> {
is_loading: bool,
block: Block<'a>,
}
impl<'a> LoadingBlock<'a> {
pub fn new(is_loading: bool, block: Block<'a>) -> Self {
Self { is_loading, block }
}
fn render_loading_block(&self, area: Rect, buf: &mut Buffer) {
if self.is_loading {
Paragraph::new(Text::from("\n\n Loading ...\n\n"))
.system_function()
.block(self.block.clone())
.render(area, buf);
} else {
self.block.clone().render(area, buf);
}
}
}
impl<'a> Widget for LoadingBlock<'a> {
fn render(self, area: Rect, buf: &mut Buffer) {
self.render_loading_block(area, buf);
}
}
+148
View File
@@ -0,0 +1,148 @@
use crate::models::StatefulTable;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::layout_block_top_border;
use crate::ui::widgets::loading_block::LoadingBlock;
use crate::ui::HIGHLIGHT_SYMBOL;
use ratatui::buffer::Buffer;
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
use ratatui::prelude::{Style, Stylize, Text};
use ratatui::widgets::{Block, Paragraph, Row, StatefulWidget, Table, Widget};
pub struct ManagarrTable<'a, T, F>
where
F: Fn(&T) -> Row<'a>,
{
content: Option<&'a mut StatefulTable<T>>,
table_headers: Vec<Text<'a>>,
constraints: Vec<Constraint>,
row_mapper: F,
footer: Option<String>,
footer_alignment: Alignment,
block: Block<'a>,
margin: u16,
is_loading: bool,
highlight_rows: bool,
}
impl<'a, T, F> ManagarrTable<'a, T, F>
where
F: Fn(&T) -> Row<'a>,
{
pub fn new(content: Option<&'a mut StatefulTable<T>>, row_mapper: F) -> Self {
Self {
content,
table_headers: Vec::new(),
constraints: Vec::new(),
row_mapper,
footer: None,
footer_alignment: Alignment::Left,
block: Block::new(),
margin: 0,
is_loading: false,
highlight_rows: true,
}
}
pub fn headers<I>(mut self, headers: I) -> Self
where
I: IntoIterator,
I::Item: Into<Text<'a>>,
{
self.table_headers = headers.into_iter().map(Into::into).collect();
self
}
pub fn constraints<I>(mut self, constraints: I) -> Self
where
I: IntoIterator,
I::Item: Into<Constraint>,
{
self.constraints = constraints.into_iter().map(Into::into).collect();
self
}
pub fn footer(mut self, footer: Option<String>) -> Self {
self.footer = footer;
self
}
pub fn footer_alignment(mut self, alignment: Alignment) -> Self {
self.footer_alignment = alignment;
self
}
pub fn block(mut self, block: Block<'a>) -> Self {
self.block = block;
self
}
pub fn margin(mut self, margin: u16) -> Self {
self.margin = margin;
self
}
pub fn loading(mut self, is_loading: bool) -> Self {
self.is_loading = is_loading;
self
}
pub fn highlight_rows(mut self, hightlight_rows: bool) -> Self {
self.highlight_rows = hightlight_rows;
self
}
fn render_table(&mut self, area: Rect, buf: &mut Buffer) {
let table_area = if let Some(ref footer) = self.footer {
let [content_area, footer_area] =
Layout::vertical([Constraint::Fill(0), Constraint::Length(2)])
.margin(self.margin)
.areas(area);
Paragraph::new(Text::from(format!(" {footer}").help()))
.block(layout_block_top_border())
.alignment(self.footer_alignment)
.render(footer_area, buf);
content_area
} else {
area
};
let loading_block = LoadingBlock::new(self.is_loading, self.block.clone());
if let Some(ref mut content) = self.content {
if !content.items.is_empty() {
let rows = content.items.iter().map(&self.row_mapper);
let headers = Row::new(self.table_headers.clone())
.default()
.bold()
.bottom_margin(0);
let mut table = Table::new(rows, &self.constraints)
.header(headers)
.block(self.block.clone());
if self.highlight_rows {
table = table
.highlight_style(Style::new().highlight())
.highlight_symbol(HIGHLIGHT_SYMBOL);
}
StatefulWidget::render(table, table_area, buf, &mut content.state);
} else {
loading_block.render(table_area, buf);
}
} else {
loading_block.render(table_area, buf);
}
}
}
impl<'a, T, F> Widget for ManagarrTable<'a, T, F>
where
F: Fn(&T) -> Row<'a>,
{
fn render(mut self, area: Rect, buf: &mut Buffer) {
self.render_table(area, buf);
}
}
+3 -1
View File
@@ -1,3 +1,5 @@
pub(super) mod button;
pub(super) mod input_box;
pub(super) mod checkbox;
pub(super) mod input_box;
pub(super) mod loading_block;
pub(super) mod managarr_table;