From 1c91ba34ac38761453a997dbe7c218e144d8ef8b Mon Sep 17 00:00:00 2001 From: YilunAllenChen Date: Fri, 10 Nov 2023 21:41:51 -0600 Subject: [PATCH] better filter management (separate menu) --- src/pages/hall.rs | 96 +++++++++--------- src/pages/hall_components/filter_mgmt.rs | 120 +++++++++++++++++++++++ src/pages/hall_components/mod.rs | 3 + src/pages/nav.rs | 12 +-- 4 files changed, 174 insertions(+), 57 deletions(-) create mode 100644 src/pages/hall_components/filter_mgmt.rs diff --git a/src/pages/hall.rs b/src/pages/hall.rs index 1690298..cbd020d 100644 --- a/src/pages/hall.rs +++ b/src/pages/hall.rs @@ -1,9 +1,10 @@ +use std::collections::HashSet; + use yew::prelude::*; use crate::artifact::{ArticleComponent, BuiltYaml, ExhibitionHall}; -use crate::html_utils::render_text_tag; use crate::html_utils::scroll::try_scroll_to; -use crate::pages::hall_components::HallNav; +use crate::pages::hall_components::{FilterMgmtMenu, HallNav}; pub struct HallComponent { active_hall: Option, @@ -68,13 +69,26 @@ impl Component for HallComponent { let yaml = include_str!("../artifacts/build/compiled.yaml"); let built_yaml: BuiltYaml = serde_yaml::from_str(yaml).unwrap(); + let mut all_available_tags = built_yaml + .artifacts + .iter() + .flat_map(|article| { + let mut article_tags = article.tags.clone(); + article_tags.push(article.language.to_string()); + article_tags + }) + .collect::>(); + let set: HashSet<_> = all_available_tags.drain(..).collect(); // dedup + all_available_tags.extend(set); + all_available_tags.sort(); + let hall_name = match &self.active_hall { Some(hall) => hall.to_string(), None => "The Everything Hall".to_string(), }; let desc = match &self.active_hall { Some(hall) => hall.desc(), - None => "You're currently viewing all artifacts. Select a hall (🏛️), or click on the tags to filter the artifacts." + None => "You're currently viewing all artifacts. Select a hall ( 🏛️ ), or click on the tags ( 🏷️ ) to filter the artifacts." }; let mut loaded_articles = built_yaml.artifacts; @@ -110,65 +124,47 @@ impl Component for HallComponent { 0 => html! {

{"This room seems to be empty 🤔..."}

-

{"Did you forget to clear your filter (🏷️)?"}

+

{"Did you forget to clear your filter ( 🏷️ )?"}

}, - _ => html! { -
-

{"You've reached the end of the this room."}

-

{"Hope you enjoyed your visit!"}

-

{"If you want to see more, check out the other halls (🏛️)!"}

-
- }, - }; - - let emitter = ctx.link().clone(); - let nav_cb = Callback::from(move |msg| emitter.send_message(msg)); - - let clear_filter_button = match self.filter_tags.len() { - 0 => html! {}, _ => { - let clear_individual_tags = self - .filter_tags - .iter() - .map(|tag| { - let tagc= tag.clone(); - html! { -
- { - Html::from_html_unchecked( - render_text_tag(tag).into() - ) - } -
- } - }) - .collect::(); + let see_more = match self.filter_tags.len() { + 0 => html! { +

+ {"If you want to see more, check out the other halls ( 🏛️ )!"} +

+ }, + _ => html! { +

+ {"If you want to see more, check out the other halls ( 🏛️ ), or clear some of your active filters ( 🏷️ )!"} +

+ }, + }; html! { -
-
-
- -
-
- {clear_individual_tags} -
-
+
+

{"You've reached the end of the this room."}

+

{"Hope you enjoyed your visit!"}

+ {see_more}
} } }; + let emitter = ctx.link().clone(); + let nav_cb = Callback::from(move |msg| emitter.send_message(msg)); + + let emitter = ctx.link().clone(); + let filter_mgmt_cb = Callback::from(move |msg| emitter.send_message(msg)); + html! { <> - {clear_filter_button} + +
diff --git a/src/pages/hall_components/filter_mgmt.rs b/src/pages/hall_components/filter_mgmt.rs new file mode 100644 index 0000000..1b98405 --- /dev/null +++ b/src/pages/hall_components/filter_mgmt.rs @@ -0,0 +1,120 @@ +use yew::*; + +use crate::{html_utils::render_text_tag, pages::HallMsg}; + +#[derive(Properties, PartialEq)] +pub struct Props { + pub hall_msg_cb: Callback, + pub available_tags: Vec, + pub filter_tags: Vec, +} + +#[function_component] +pub fn FilterMgmtMenu(props: &Props) -> Html { + let show_menu = use_state(|| !props.filter_tags.is_empty()); + + let toggle_popup = { + let show_popup = show_menu.clone(); + Callback::from(move |_| show_popup.set(!*show_popup)) + }; + + let menu_btn = html! { +
+
+
+ +
+
+
+ }; + + let tag_to_toggle_button = |tag: &String| { + let tagc = tag.clone(); + html! { +
+ { Html::from_html_unchecked( render_text_tag(tag).into()) } +
+ } + }; + + let enable_tag = props + .available_tags + .iter() + .filter(|tag| !props.filter_tags.contains(tag)) + .map(tag_to_toggle_button) + .collect::(); + + let clear_individual_tags = match props.filter_tags.len() { + 0 => html! { +

{"No active filters"}

+ }, + _ => props + .filter_tags + .iter() + .filter(|tag| props.available_tags.contains(tag)) + .map(tag_to_toggle_button) + .collect::(), + }; + + let menu = html! { +
+
+
+
+
+

+ {"Filter Management"} +

+ + +

+ {"Active Filters"} +

+
+ {clear_individual_tags} +
+ +

+ {"Available Filters"} +

+
+ {enable_tag} +
+ +
+

+ {"Clear All"} +

+

+ {"Close"} +

+
+
+
+
+
+ }; + + match *show_menu { + false => html! { + {menu_btn} + }, + true => html! { + {menu} + }, + } +} diff --git a/src/pages/hall_components/mod.rs b/src/pages/hall_components/mod.rs index 8b42f8b..c01f07d 100644 --- a/src/pages/hall_components/mod.rs +++ b/src/pages/hall_components/mod.rs @@ -1,2 +1,5 @@ mod hall_nav; pub use hall_nav::HallNav; + +mod filter_mgmt; +pub use filter_mgmt::FilterMgmtMenu; diff --git a/src/pages/nav.rs b/src/pages/nav.rs index 46432c3..165bdc4 100644 --- a/src/pages/nav.rs +++ b/src/pages/nav.rs @@ -4,7 +4,7 @@ use yew_router::scope_ext::RouterScopeExt; use crate::Route; pub struct Nav { - show_sidebar: bool, + show_nav: bool, } #[derive(Properties, PartialEq)] @@ -20,9 +20,7 @@ impl Component for Nav { type Properties = NavProps; fn create(_ctx: &Context) -> Self { - Self { - show_sidebar: false, - } + Self { show_nav: false } } fn changed(&mut self, _ctx: &Context, _old_props: &Self::Properties) -> bool { @@ -32,11 +30,11 @@ impl Component for Nav { fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { match msg { Msg::ToggleSidebar(show) => { - self.show_sidebar = show; + self.show_nav = show; true } Msg::SelectPage(page) => { - self.show_sidebar = false; + self.show_nav = false; let navigator = ctx.link().navigator().unwrap(); navigator.push(&page); true @@ -45,7 +43,7 @@ impl Component for Nav { } fn view(&self, ctx: &Context) -> Html { - if !self.show_sidebar { + if !self.show_nav { html! {