[pdm-devel] [PATCH datacenter-manager 2/3] ui: dashboard: refactor remotes panel

Dominik Csapak d.csapak at proxmox.com
Fri Apr 11 16:05:19 CEST 2025


put the remotes panel into it's own component to keep the dashboard code
shorter when adding more functionality here.

Signed-off-by: Dominik Csapak <d.csapak at proxmox.com>
---
 ui/src/dashboard/mod.rs          | 38 ++++----------
 ui/src/dashboard/remote_panel.rs | 90 ++++++++++++++++++++++++++++++++
 2 files changed, 99 insertions(+), 29 deletions(-)
 create mode 100644 ui/src/dashboard/remote_panel.rs

diff --git a/ui/src/dashboard/mod.rs b/ui/src/dashboard/mod.rs
index ea0cf5e..016fccb 100644
--- a/ui/src/dashboard/mod.rs
+++ b/ui/src/dashboard/mod.rs
@@ -26,6 +26,9 @@ pub use top_entities::TopEntities;
 mod subscription_info;
 pub use subscription_info::SubscriptionInfo;
 
+mod remote_panel;
+use remote_panel::RemotePanel;
+
 #[derive(Properties, PartialEq)]
 pub struct Dashboard {
     #[prop_or(60)]
@@ -260,19 +263,7 @@ impl Component for PdmDashboard {
         }
     }
 
-    fn view(&self, _ctx: &yew::Context<Self>) -> yew::Html {
-        let (remote_icon, remote_text) = match (self.status.failed_remotes, self.status.remotes) {
-            (0, 0) => (Status::Warning.to_fa_icon(), tr!("No remotes configured.")),
-            (0, _) => (
-                Status::Success.to_fa_icon(),
-                tr!("Could reach all remotes."),
-            ),
-            (failed, _) => (
-                Status::Error.to_fa_icon(),
-                tr!("{0} remotes failed to reach.", failed),
-            ),
-        };
-
+    fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
         let content = Column::new()
             .class(FlexFit)
             .with_child(
@@ -290,22 +281,11 @@ impl Component for PdmDashboard {
                             .with_tool(
                                 Button::new(tr!("Add"))
                                     .icon_class("fa fa-plus-circle")
-                                    .onclick(_ctx.link().callback(|_| Msg::CreateWizard(true))),
+                                    .onclick(ctx.link().callback(|_| Msg::CreateWizard(true))),
                             )
-                            .with_child(
-                                Column::new()
-                                    .padding(4)
-                                    .class(FlexFit)
-                                    .class(AlignItems::Center)
-                                    .class(JustifyContent::Center)
-                                    .gap(2)
-                                    .with_child(if self.loading {
-                                        html! {<i class={"pwt-loading-icon"} />}
-                                    } else {
-                                        remote_icon.large_4x().into()
-                                    })
-                                    .with_optional_child((!self.loading).then_some(remote_text)),
-                            ),
+                            .with_child(RemotePanel::new(
+                                (!self.loading).then_some(self.status.clone()),
+                            )),
                     )
                     .with_child(self.create_node_panel(
                         "building",
@@ -423,7 +403,7 @@ impl Component for PdmDashboard {
             .with_optional_child(
                 self.show_wizard.then_some(
                     AddWizard::new(pdm_api_types::remotes::RemoteType::Pve)
-                        .on_close(_ctx.link().callback(|_| Msg::CreateWizard(false)))
+                        .on_close(ctx.link().callback(|_| Msg::CreateWizard(false)))
                         .on_submit(move |ctx| {
                             crate::remotes::create_remote(
                                 ctx,
diff --git a/ui/src/dashboard/remote_panel.rs b/ui/src/dashboard/remote_panel.rs
new file mode 100644
index 0000000..2c1dd75
--- /dev/null
+++ b/ui/src/dashboard/remote_panel.rs
@@ -0,0 +1,90 @@
+use std::rc::Rc;
+
+use proxmox_yew_comp::Status;
+use pwt::{
+    css,
+    prelude::*,
+    props::{ContainerBuilder, WidgetBuilder},
+    widget::{Column, Container, Fa},
+};
+use yew::{
+    virtual_dom::{VComp, VNode},
+    Component, Properties,
+};
+
+use pdm_api_types::resource::ResourcesStatus;
+
+#[derive(Properties, PartialEq)]
+/// A panel for showing the overall remotes status
+pub struct RemotePanel {
+    /// The status loaded from the API
+    pub status: Option<ResourcesStatus>,
+}
+
+impl RemotePanel {
+    /// Takes the status of the API, or None (which indicates loading)
+    pub fn new(status: Option<ResourcesStatus>) -> Self {
+        yew::props!(Self { status })
+    }
+}
+
+impl From<RemotePanel> for VNode {
+    fn from(val: RemotePanel) -> Self {
+        let comp = VComp::new::<PdmRemotePanel>(Rc::new(val), None);
+        VNode::from(comp)
+    }
+}
+
+struct PdmRemotePanel {}
+
+impl Component for PdmRemotePanel {
+    type Message = &'static str;
+    type Properties = RemotePanel;
+
+    fn create(_ctx: &yew::Context<Self>) -> Self {
+        Self {}
+    }
+
+    fn view(&self, ctx: &yew::Context<Self>) -> yew::Html {
+        let props = ctx.props();
+        if props.status.is_none() {
+            return Column::new()
+                .padding(4)
+                .class(css::FlexFit)
+                .class(css::AlignItems::Center)
+                .class(css::JustifyContent::Center)
+                .with_child(Fa::new("").class("pwt-loading-icon"))
+                .into();
+        }
+        let status = props.status.clone().unwrap();
+
+        let (remote_icon, remote_text, failure) = match (status.failed_remotes, status.remotes) {
+            (0, 0) => (
+                Status::Warning.to_fa_icon(),
+                tr!("No remotes configured."),
+                false,
+            ),
+            (0, _) => (
+                Status::Success.to_fa_icon(),
+                tr!("Could reach all remotes."),
+                false,
+            ),
+            (failed, _) => (
+                Status::Error.to_fa_icon(),
+                tr!("{0} remotes failed to reach.", failed),
+                true,
+            ),
+        };
+        Column::new()
+            .tabindex(if failure { 0 } else { -1 })
+            .padding(4)
+            .class(css::FlexFit)
+            .class(css::AlignItems::Center)
+            .class(css::JustifyContent::Center)
+            .style("cursor", failure.then_some("pointer"))
+            .gap(2)
+            .with_child(remote_icon.large_4x())
+            .with_child(Container::new().with_child(remote_text))
+            .into()
+    }
+}
-- 
2.39.5





More information about the pdm-devel mailing list