all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pdm-devel] [PATCH datacenter-manager] ui: search box: close if user navigated to an entry
@ 2025-09-05  7:29 Dominik Csapak
  2025-09-05 12:34 ` [pdm-devel] applied: " Thomas Lamprecht
  0 siblings, 1 reply; 2+ messages in thread
From: Dominik Csapak @ 2025-09-05  7:29 UTC (permalink / raw)
  To: pdm-devel

either by clicking or using the keyboard. For this we need to add a new
'on_navigate' callback in the ResourceTree that triggers when the user
navigated away.

While at it, refactor the navigation callbacks into the update method.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 ui/src/widget/resource_tree.rs | 66 ++++++++++++++++++----------------
 ui/src/widget/search_box.rs    |  6 ++++
 2 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/ui/src/widget/resource_tree.rs b/ui/src/widget/resource_tree.rs
index aefcaf6..708df65 100644
--- a/ui/src/widget/resource_tree.rs
+++ b/ui/src/widget/resource_tree.rs
@@ -4,7 +4,7 @@ use anyhow::Error;
 use gloo_timers::callback::Timeout;
 use serde_json::json;
 use web_sys::window;
-use yew::{virtual_dom::Key, Component};
+use yew::{html::IntoEventCallback, virtual_dom::Key, Component};
 
 use pwt::{
     css::{FlexFit, FontColor},
@@ -48,6 +48,11 @@ pub struct ResourceTree {
     #[builder]
     /// If this is true, we wait with the load until we have a search term
     pub search_only: bool,
+
+    #[prop_or_default]
+    #[builder_cb(IntoEventCallback, into_event_callback, ())]
+    /// Triggered after the user navigated to an entry by clicking or using the keyboard
+    pub on_navigate: Option<Callback<()>>,
 }
 
 impl ResourceTree {
@@ -91,6 +96,7 @@ pub enum Msg {
     Load,
     LoadResult(Result<Vec<RemoteResources>, Error>),
     RemoteListChanged(RemoteList),
+    NavigateToEntry(Key),
 }
 
 pub struct PdmResourceTree {
@@ -193,6 +199,32 @@ impl Component for PdmResourceTree {
                 }
                 true
             }
+            Msg::NavigateToEntry(key) => {
+                let store = self.store.read();
+                let root = store.root().unwrap();
+
+                let mut navigated = false;
+                if let Some(node) = root.find_node_by_key(&key) {
+                    match node.record() {
+                        PdmTreeEntry::Root => {}
+                        PdmTreeEntry::Resource(remote, resource) => {
+                            crate::navigate_to(ctx.link(), remote, Some(resource));
+                            navigated = true;
+                        }
+                        PdmTreeEntry::Remote(remote, _) => {
+                            crate::navigate_to(ctx.link(), remote, None);
+                            navigated = true;
+                        }
+                    }
+                }
+
+                if navigated {
+                    if let Some(cb) = &ctx.props().on_navigate {
+                        cb.emit(());
+                    }
+                }
+                false
+            }
         }
     }
 
@@ -217,30 +249,16 @@ impl Component for PdmResourceTree {
         let table = DataTable::new(columns(ctx.link(), self.store.clone()), self.store.clone())
             .selection(self.selection.clone())
             .on_row_click({
-                let store = self.store.clone();
                 let link = ctx.link().clone();
                 move |event: &mut DataTableMouseEvent| {
-                    let store = store.read();
-                    let root = store.root().unwrap();
-
-                    if let Some(node) = root.find_node_by_key(&event.record_key) {
-                        navigate_to_entry(&link, node.record());
-                    }
+                    link.send_message(Msg::NavigateToEntry(event.record_key.clone()));
                 }
             })
             .on_row_keydown({
-                let store = self.store.clone();
                 let link = ctx.link().clone();
                 move |event: &mut DataTableKeyboardEvent| {
-                    let store = store.read();
-                    let root = store.root().unwrap();
-
-                    if event.key().as_str() != "Enter" {
-                        return;
-                    }
-
-                    if let Some(node) = root.find_node_by_key(&event.record_key) {
-                        navigate_to_entry(&link, node.record());
+                    if let "Enter" | " " = event.key().as_str() {
+                        link.send_message(Msg::NavigateToEntry(event.record_key.clone()))
                     }
                 }
             })
@@ -286,18 +304,6 @@ impl Component for PdmResourceTree {
     }
 }
 
-fn navigate_to_entry(link: &html::Scope<PdmResourceTree>, record: &PdmTreeEntry) {
-    match record {
-        PdmTreeEntry::Root => {}
-        PdmTreeEntry::Resource(remote, resource) => {
-            crate::navigate_to(link, remote, Some(resource));
-        }
-        PdmTreeEntry::Remote(remote, _) => {
-            crate::navigate_to(link, remote, None);
-        }
-    }
-}
-
 fn columns(
     link: &html::Scope<PdmResourceTree>,
     store: TreeStore<PdmTreeEntry>,
diff --git a/ui/src/widget/search_box.rs b/ui/src/widget/search_box.rs
index 52bb156..3a52411 100644
--- a/ui/src/widget/search_box.rs
+++ b/ui/src/widget/search_box.rs
@@ -40,6 +40,7 @@ pub enum Msg {
     ChangeTerm(String, bool), // force value
     FocusChange(bool),
     ToggleFocus,
+    NavigatedToEntry,
 }
 
 pub struct PdmSearchBox {
@@ -105,6 +106,10 @@ impl Component for PdmSearchBox {
                 self.toggle_focus = true;
                 true
             }
+            Msg::NavigatedToEntry => {
+                self.focus = false;
+                true
+            }
         }
     }
 
@@ -126,6 +131,7 @@ impl Component for PdmSearchBox {
             .border(true)
             .width(CssLength::Fraction(0.5))
             .height(400)
+            .on_navigate(ctx.link().callback(|_| Msg::NavigatedToEntry))
             .class("pwt-shadow2");
 
         let clear_trigger_icon = if self.search_term.is_empty() {
-- 
2.47.2



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-09-05 12:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-05  7:29 [pdm-devel] [PATCH datacenter-manager] ui: search box: close if user navigated to an entry Dominik Csapak
2025-09-05 12:34 ` [pdm-devel] applied: " Thomas Lamprecht

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal