feat(models): Created the EditSeriesModal

This commit is contained in:
2024-11-25 15:44:07 -07:00
parent 97dc5054e9
commit 06c9baf8df
5 changed files with 232 additions and 2 deletions
+105 -1
View File
@@ -3,7 +3,7 @@ use strum::IntoEnumIterator;
use crate::models::{
servarr_data::modals::EditIndexerModal,
servarr_models::{Indexer, RootFolder},
sonarr_models::{Episode, SeriesMonitor, SeriesType, SonarrHistoryItem, SonarrRelease},
sonarr_models::{Episode, Series, SeriesMonitor, SeriesType, SonarrHistoryItem, SonarrRelease},
stateful_list::StatefulList,
stateful_table::StatefulTable,
HorizontallyScrollableText, ScrollableText,
@@ -142,6 +142,110 @@ impl From<&SonarrData> for EditIndexerModal {
}
}
#[derive(Default)]
pub struct EditSeriesModal {
pub series_type_list: StatefulList<SeriesType>,
pub quality_profile_list: StatefulList<String>,
pub language_profile_list: StatefulList<String>,
pub monitored: Option<bool>,
pub use_season_folders: Option<bool>,
pub path: HorizontallyScrollableText,
pub tags: HorizontallyScrollableText,
}
impl From<&SonarrData> for EditSeriesModal {
fn from(sonarr_data: &SonarrData) -> EditSeriesModal {
let mut edit_series_modal = EditSeriesModal::default();
let Series {
path,
tags,
monitored,
season_folder,
series_type,
quality_profile_id,
language_profile_id,
..
} = sonarr_data.series.current_selection();
edit_series_modal
.series_type_list
.set_items(Vec::from_iter(SeriesType::iter()));
edit_series_modal.path = path.clone().into();
edit_series_modal.tags = tags
.iter()
.map(|tag_id| {
sonarr_data
.tags_map
.get_by_left(&tag_id.as_i64().unwrap())
.unwrap()
.clone()
})
.collect::<Vec<String>>()
.join(", ")
.into();
edit_series_modal.monitored = Some(*monitored);
edit_series_modal.use_season_folders = Some(*season_folder);
let series_type_index = edit_series_modal
.series_type_list
.items
.iter()
.position(|st| st == series_type);
edit_series_modal
.series_type_list
.state
.select(series_type_index);
let mut quality_profile_names: Vec<String> = sonarr_data
.quality_profile_map
.right_values()
.cloned()
.collect();
quality_profile_names.sort();
edit_series_modal
.quality_profile_list
.set_items(quality_profile_names);
let quality_profile_name = sonarr_data
.quality_profile_map
.get_by_left(quality_profile_id)
.unwrap();
let quality_profile_index = edit_series_modal
.quality_profile_list
.items
.iter()
.position(|profile| profile == quality_profile_name);
edit_series_modal
.quality_profile_list
.state
.select(quality_profile_index);
let mut language_profile_names: Vec<String> = sonarr_data
.language_profiles_map
.right_values()
.cloned()
.collect();
language_profile_names.sort();
edit_series_modal
.language_profile_list
.set_items(language_profile_names);
let language_profile_name = sonarr_data
.language_profiles_map
.get_by_left(language_profile_id)
.unwrap();
let language_profile_index = edit_series_modal
.language_profile_list
.items
.iter()
.position(|profile| profile == language_profile_name);
edit_series_modal
.language_profile_list
.state
.select(language_profile_index);
edit_series_modal
}
}
#[derive(Default)]
pub struct EpisodeDetailsModal {
pub episode_details: ScrollableText,
@@ -5,12 +5,14 @@ mod tests {
use rstest::rstest;
use strum::IntoEnumIterator;
use crate::models::servarr_data::sonarr::modals::EditSeriesModal;
use crate::models::servarr_models::{Indexer, IndexerField};
use crate::models::{
servarr_data::sonarr::{modals::AddSeriesModal, sonarr_data::SonarrData},
servarr_models::RootFolder,
sonarr_models::{SeriesMonitor, SeriesType},
};
use crate::models::{sonarr_models::Series, stateful_table::StatefulTable};
use serde_json::{Number, Value};
use crate::models::servarr_data::modals::EditIndexerModal;
@@ -112,4 +114,111 @@ mod tests {
assert!(edit_indexer_modal.seed_ratio.text.is_empty());
}
}
#[test]
fn test_edit_indexer_modal_from_sonarr_data_seed_ratio_value_is_none() {
let mut sonarr_data = SonarrData {
tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]),
..SonarrData::default()
};
let fields = vec![
IndexerField {
name: Some("baseUrl".to_owned()),
value: Some(Value::String("https://test.com".to_owned())),
},
IndexerField {
name: Some("apiKey".to_owned()),
value: Some(Value::String("1234".to_owned())),
},
IndexerField {
name: Some("seedCriteria.seedRatio".to_owned()),
value: None,
},
];
let indexer = Indexer {
name: Some("Test".to_owned()),
enable_rss: true,
enable_automatic_search: true,
enable_interactive_search: true,
tags: vec![Number::from(1), Number::from(2)],
fields: Some(fields),
..Indexer::default()
};
sonarr_data.indexers.set_items(vec![indexer]);
let edit_indexer_modal = EditIndexerModal::from(&sonarr_data);
assert_str_eq!(edit_indexer_modal.name.text, "Test");
assert_eq!(edit_indexer_modal.enable_rss, Some(true));
assert_eq!(edit_indexer_modal.enable_automatic_search, Some(true));
assert_eq!(edit_indexer_modal.enable_interactive_search, Some(true));
assert_str_eq!(edit_indexer_modal.url.text, "https://test.com");
assert_str_eq!(edit_indexer_modal.api_key.text, "1234");
assert!(edit_indexer_modal.seed_ratio.text.is_empty());
}
#[rstest]
fn test_edit_series_modal_from_sonarr_data(#[values(true, false)] test_filtered_series: bool) {
let mut sonarr_data = SonarrData {
quality_profile_map: BiMap::from_iter([
(2222, "HD - 1080p".to_owned()),
(1111, "Any".to_owned()),
]),
language_profiles_map: BiMap::from_iter([
(2222, "English".to_owned()),
(1111, "Any".to_owned()),
]),
tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]),
series: StatefulTable::default(),
..SonarrData::default()
};
let series = Series {
path: "/nfs/seriess/Test".to_owned(),
monitored: true,
season_folder: true,
quality_profile_id: 2222,
language_profile_id: 2222,
series_type: SeriesType::Anime,
tags: vec![Number::from(1), Number::from(2)],
..Series::default()
};
if test_filtered_series {
sonarr_data.series.set_filtered_items(vec![series]);
} else {
sonarr_data.series.set_items(vec![series]);
}
let edit_series_modal = EditSeriesModal::from(&sonarr_data);
assert_eq!(
edit_series_modal.series_type_list.items,
Vec::from_iter(SeriesType::iter())
);
assert_eq!(
edit_series_modal.series_type_list.current_selection(),
&SeriesType::Anime,
);
assert_eq!(
edit_series_modal.quality_profile_list.items,
vec!["Any".to_owned(), "HD - 1080p".to_owned()]
);
assert_str_eq!(
edit_series_modal.quality_profile_list.current_selection(),
"HD - 1080p"
);
assert_eq!(
edit_series_modal.language_profile_list.items,
vec!["Any".to_owned(), "English".to_owned()]
);
assert_str_eq!(
edit_series_modal.language_profile_list.current_selection(),
"English"
);
assert_str_eq!(edit_series_modal.path.text, "/nfs/seriess/Test");
assert_str_eq!(edit_series_modal.tags.text, "usenet, test");
assert_eq!(edit_series_modal.monitored, Some(true));
assert_eq!(edit_series_modal.use_season_folders, Some(true));
}
}
@@ -14,7 +14,7 @@ use crate::models::{
HorizontallyScrollableText, Route, ScrollableText,
};
use super::modals::{AddSeriesModal, SeasonDetailsModal};
use super::modals::{AddSeriesModal, EditSeriesModal, SeasonDetailsModal};
#[cfg(test)]
#[path = "sonarr_data_tests.rs"]
@@ -31,6 +31,7 @@ pub struct SonarrData {
pub disk_space_vec: Vec<DiskSpace>,
pub edit_indexer_modal: Option<EditIndexerModal>,
pub edit_root_folder: Option<HorizontallyScrollableText>,
pub edit_series_modal: Option<EditSeriesModal>,
pub history: StatefulTable<SonarrHistoryItem>,
pub indexers: StatefulTable<Indexer>,
pub indexer_settings: Option<IndexerSettings>,
@@ -72,6 +73,7 @@ impl Default for SonarrData {
disk_space_vec: Vec::new(),
edit_indexer_modal: None,
edit_root_folder: None,
edit_series_modal: None,
history: StatefulTable::default(),
indexers: StatefulTable::default(),
indexer_settings: None,
@@ -58,6 +58,7 @@ mod tests {
assert!(sonarr_data.disk_space_vec.is_empty());
assert!(sonarr_data.edit_indexer_modal.is_none());
assert!(sonarr_data.edit_root_folder.is_none());
assert!(sonarr_data.edit_series_modal.is_none());
assert!(sonarr_data.history.is_empty());
assert!(sonarr_data.indexers.is_empty());
assert!(sonarr_data.indexer_settings.is_none());
+14
View File
@@ -128,6 +128,20 @@ pub struct DownloadsResponse {
pub records: Vec<DownloadRecord>,
}
#[derive(Default, Clone, Serialize, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct EditSeriesParams {
pub series_id: i64,
pub monitored: Option<bool>,
pub use_season_folders: Option<bool>,
pub quality_profile_id: Option<i64>,
pub language_profile_id: Option<i64>,
pub series_type: Option<SeriesType>,
pub root_folder_path: Option<String>,
pub tags: Option<Vec<i64>>,
pub clear_tags: bool,
}
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Episode {