[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