feat(ui): Root folder tab support

This commit is contained in:
2024-12-03 16:24:23 -07:00
parent bda6f253e0
commit 8660de530d
3 changed files with 139 additions and 0 deletions
+3
View File
@@ -12,6 +12,7 @@ use ratatui::{
widgets::Paragraph, widgets::Paragraph,
Frame, Frame,
}; };
use root_folders::RootFoldersUi;
use crate::{ use crate::{
app::App, app::App,
@@ -39,6 +40,7 @@ mod blocklist;
mod downloads; mod downloads;
mod history; mod history;
mod library; mod library;
mod root_folders;
#[cfg(test)] #[cfg(test)]
#[path = "sonarr_ui_tests.rs"] #[path = "sonarr_ui_tests.rs"]
@@ -60,6 +62,7 @@ impl DrawUi for SonarrUi {
_ if DownloadsUi::accepts(route) => DownloadsUi::draw(f, app, content_area), _ if DownloadsUi::accepts(route) => DownloadsUi::draw(f, app, content_area),
_ if BlocklistUi::accepts(route) => BlocklistUi::draw(f, app, content_area), _ if BlocklistUi::accepts(route) => BlocklistUi::draw(f, app, content_area),
_ if HistoryUi::accepts(route) => HistoryUi::draw(f, app, content_area), _ if HistoryUi::accepts(route) => HistoryUi::draw(f, app, content_area),
_ if RootFoldersUi::accepts(route) => RootFoldersUi::draw(f, app, content_area),
_ => (), _ => (),
} }
} }
+117
View File
@@ -0,0 +1,117 @@
use ratatui::layout::{Constraint, Rect};
use ratatui::widgets::{Cell, Row};
use ratatui::Frame;
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ROOT_FOLDERS_BLOCKS};
use crate::models::servarr_models::RootFolder;
use crate::models::Route;
use crate::ui::styles::ManagarrStyle;
use crate::ui::utils::layout_block_top_border;
use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt;
use crate::ui::widgets::managarr_table::ManagarrTable;
use crate::ui::widgets::popup::{Popup, Size};
use crate::ui::{draw_input_box_popup, draw_popup_over, DrawUi};
use crate::utils::convert_to_gb;
#[cfg(test)]
#[path = "root_folders_ui_tests.rs"]
mod root_folders_ui_tests;
pub(super) struct RootFoldersUi;
impl DrawUi for RootFoldersUi {
fn accepts(route: Route) -> bool {
if let Route::Sonarr(active_sonarr_block, _) = route {
return ROOT_FOLDERS_BLOCKS.contains(&active_sonarr_block);
}
false
}
fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
if let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() {
match active_sonarr_block {
ActiveSonarrBlock::RootFolders => draw_root_folders(f, app, area),
ActiveSonarrBlock::AddRootFolderPrompt => draw_popup_over(
f,
app,
area,
draw_root_folders,
draw_add_root_folder_prompt_box,
Size::InputBox,
),
ActiveSonarrBlock::DeleteRootFolderPrompt => {
let prompt = format!(
"Do you really want to delete this root folder: \n{}?",
app.data.sonarr_data.root_folders.current_selection().path
);
let confirmation_prompt = ConfirmationPrompt::new()
.title("Delete Root Folder")
.prompt(&prompt)
.yes_no_value(app.data.sonarr_data.prompt_confirm);
draw_root_folders(f, app, area);
f.render_widget(Popup::new(confirmation_prompt).size(Size::Prompt), f.area());
}
_ => (),
}
}
}
}
fn draw_root_folders(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
let help_footer = app
.data
.sonarr_data
.main_tabs
.get_active_tab_contextual_help();
let root_folders_row_mapping = |root_folders: &RootFolder| {
let RootFolder {
path,
free_space,
unmapped_folders,
..
} = root_folders;
let space: f64 = convert_to_gb(*free_space);
Row::new(vec![
Cell::from(path.to_owned()),
Cell::from(format!("{space:.2} GB")),
Cell::from(
unmapped_folders
.as_ref()
.unwrap_or(&Vec::new())
.len()
.to_string(),
),
])
.primary()
};
let root_folders_table = ManagarrTable::new(
Some(&mut app.data.sonarr_data.root_folders),
root_folders_row_mapping,
)
.block(layout_block_top_border())
.loading(app.is_loading)
.footer(help_footer)
.headers(["Path", "Free Space", "Unmapped Folders"])
.constraints([
Constraint::Ratio(3, 5),
Constraint::Ratio(1, 5),
Constraint::Ratio(1, 5),
]);
f.render_widget(root_folders_table, area);
}
fn draw_add_root_folder_prompt_box(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
draw_input_box_popup(
f,
area,
"Add Root Folder",
app.data.sonarr_data.edit_root_folder.as_ref().unwrap(),
);
}
@@ -0,0 +1,19 @@
#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ROOT_FOLDERS_BLOCKS};
use crate::ui::sonarr_ui::root_folders::RootFoldersUi;
use crate::ui::DrawUi;
#[test]
fn test_root_folders_ui_accepts() {
ActiveSonarrBlock::iter().for_each(|active_sonarr_block| {
if ROOT_FOLDERS_BLOCKS.contains(&active_sonarr_block) {
assert!(RootFoldersUi::accepts(active_sonarr_block.into()));
} else {
assert!(!RootFoldersUi::accepts(active_sonarr_block.into()));
}
});
}
}