From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id A8EE81FF15E for ; Mon, 10 Nov 2025 09:57:52 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8FDD5101F8; Mon, 10 Nov 2025 09:58:35 +0100 (CET) From: Shannon Sterz To: pdm-devel@lists.proxmox.com Date: Mon, 10 Nov 2025 09:58:30 +0100 Message-ID: <20251110085830.21887-4-s.sterz@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20251110085830.21887-1-s.sterz@proxmox.com> References: <20251110085830.21887-1-s.sterz@proxmox.com> MIME-Version: 1.0 X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1762765089845 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.062 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pdm-devel] [PATCH datacenter-manager v3 1/1] ui: add a Node Status tab to the administration panel X-BeenThere: pdm-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Datacenter Manager development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pdm-devel-bounces@lists.proxmox.com Sender: "pdm-devel" it show the current node status via the new NodeStatPanel and has buttons for shutting down and rebooting the node. Signed-off-by: Shannon Sterz --- the setup in NodeStatus here should make it fairly trivial to add more panels here in the future and have the layout be similar to the current dashboard. ui/src/administration/mod.rs | 9 +++ ui/src/administration/node_status.rs | 114 +++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 ui/src/administration/node_status.rs diff --git a/ui/src/administration/mod.rs b/ui/src/administration/mod.rs index a9f7ac6..e37b59c 100644 --- a/ui/src/administration/mod.rs +++ b/ui/src/administration/mod.rs @@ -18,6 +18,8 @@ use pwt_macros::builder; use proxmox_yew_comp::{AptPackageManager, AptRepositories, ExistingProduct, Syslog, Tasks}; +mod node_status; + #[derive(Clone, PartialEq, Properties)] #[builder] pub struct ServerAdministration { @@ -67,6 +69,13 @@ impl Component for PdmServerAdministration { |_| Services::new().into(), ) */ + .with_item_builder( + TabBarItem::new() + .key("status") + .label(tr!("Node Status")) + .icon_class("fa fa-book"), + move |_| node_status::NodeStatus::new().into(), + ) .with_item_builder( TabBarItem::new() .key("updates") diff --git a/ui/src/administration/node_status.rs b/ui/src/administration/node_status.rs new file mode 100644 index 0000000..953a728 --- /dev/null +++ b/ui/src/administration/node_status.rs @@ -0,0 +1,114 @@ +use std::rc::Rc; + +use anyhow::Error; +use yew::virtual_dom::{VComp, VNode}; + +use proxmox_node_status::NodePowerCommand; +use proxmox_yew_comp::{http_post, ConfirmButton, NodeStatusPanel}; +use pwt::prelude::*; +use pwt::widget::{Column, Container, Row}; + +#[derive(Properties, Clone, PartialEq)] +pub(crate) struct NodeStatus {} + +impl NodeStatus { + pub(crate) fn new() -> Self { + yew::props!(Self {}) + } +} + +impl From for VNode { + fn from(value: NodeStatus) -> Self { + VComp::new::(Rc::new(value), None).into() + } +} + +enum Msg { + Reload, + Error(Error), + RebootOrShutdown(NodePowerCommand), +} + +struct PdmNodeStatus { + error: Option, +} + +impl PdmNodeStatus { + fn change_power_state(&self, ctx: &yew::Context, command: NodePowerCommand) { + ctx.link().send_future(async move { + let data = Some(serde_json::json!({"command": command})); + + match http_post("/nodes/localhost/status", data).await { + Ok(()) => Msg::Reload, + Err(e) => Msg::Error(e), + } + }); + } +} + +impl Component for PdmNodeStatus { + type Message = Msg; + type Properties = NodeStatus; + + fn create(_ctx: &yew::Context) -> Self { + Self { error: None } + } + + fn update(&mut self, ctx: &yew::Context, msg: Self::Message) -> bool { + match msg { + Msg::RebootOrShutdown(command) => { + self.change_power_state(ctx, command); + false + } + Msg::Error(e) => { + self.error = Some(e); + true + } + Msg::Reload => true, + } + } + + fn view(&self, ctx: &yew::Context) -> Html { + Column::new() + .class(pwt::css::FlexFit) + .with_child( + Container::new() + .class("pwt-content-spacer-padding") + .class("pwt-content-spacer-colors") + .class("pwt-default-colors") + .with_child( + Row::new() + .gap(1) + .with_child( + ConfirmButton::new(tr!("Reboot")) + .confirm_message(tr!( + "Are you sure you want to reboot the node?" + )) + .on_activate(ctx.link().callback(|_| { + Msg::RebootOrShutdown(NodePowerCommand::Reboot) + })) + .class(pwt::css::ColorScheme::Neutral) + .icon_class("fa fa-undo"), + ) + .with_child( + ConfirmButton::new(tr!("Shutdown")) + .confirm_message(tr!( + "Are you sure you want to shut down the node?" + )) + .on_activate(ctx.link().callback(|_| { + Msg::RebootOrShutdown(NodePowerCommand::Shutdown) + })) + .class(pwt::css::ColorScheme::Neutral) + .icon_class("fa fa-power-off"), + ), + ), + ) + .with_child( + Row::new() + .class("pwt-content-spacer") + .class(pwt::css::FlexFit) + .with_child(NodeStatusPanel::new().status_base_url("/nodes/localhost/status")), + ) + .into() + } +} -- 2.47.3 _______________________________________________ pdm-devel mailing list pdm-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel