use uuid::Uuid; use crate::{projects::Project, teams::Team}; #[derive(Clone, Debug, Default)] pub struct Breadcrumb { pub href: String, pub label: String, } // TODO: This is a very quick, dirty, and awkward approach to storing // navigation state. It can and should be scrapped and replaced when time // allows. #[derive(Clone, Debug, Default)] pub struct NavState { pub base_path: String, pub breadcrumbs: Vec, pub team_id: Option, pub navbar_active_item: String, } impl NavState { pub fn new() -> Self { Self::default() } pub fn set_base_path(mut self, base_path: &str) -> Self { self.base_path = base_path.to_string(); self } pub fn push_team(mut self, team: &Team) -> Self { self.team_id = Some(team.id.clone()); self.navbar_active_item = "teams".to_string(); self.breadcrumbs.push(Breadcrumb { href: format!("{}/teams", self.base_path), label: "Teams".to_string(), }); self.breadcrumbs.push(Breadcrumb { href: format!("{}/teams/{}", self.base_path, team.id.clone().simple()), label: team.name.clone(), }); self } pub fn push_project(mut self, project: &Project) -> Result { let team_id = self.team_id.ok_or(anyhow::anyhow!( "NavState.push_project() called out of order" ))?; self.navbar_active_item = "projects".to_string(); self.breadcrumbs.push(Breadcrumb { href: format!("{}/teams/{}/projects", self.base_path, team_id), label: "Projects".to_string(), }); self.breadcrumbs.push(Breadcrumb { href: format!( "{}/teams/{}/projects/{}", self.base_path, team_id, project.id.clone().simple() ), label: project.name.clone(), }); Ok(self) } /** * Add a breadcrumb with an href treated as a child of the previous * breadcrumb's path (or of the base_path if no breadcrumbs exist). */ pub fn push_slug(mut self, breadcrumb: Breadcrumb) -> Self { let starting_path = self .breadcrumbs .iter() .last() .map(|breadcrumb| breadcrumb.href.clone()) .unwrap_or(self.base_path.clone()); self.breadcrumbs.push(Breadcrumb { href: format!("{}/{}", starting_path, breadcrumb.href), label: breadcrumb.label, }); self } pub fn set_navbar_active_item(mut self, value: &str) -> Self { self.navbar_active_item = value.to_string(); self } }