From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 553E61FF179 for ; Wed, 15 Oct 2025 10:15:11 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 94D0914EBA; Wed, 15 Oct 2025 10:15:30 +0200 (CEST) From: Dietmar Maurer To: pdm-devel@lists.proxmox.com Date: Wed, 15 Oct 2025 10:15:21 +0200 Message-ID: <20251015081524.2863240-1-dietmar@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.585 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 KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pdm-devel] [PATCH datacenter-manager 1/4] ui: qemu: move files into subfolder, add Tabbar on top 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" So that we can add other tab panels in the future, Signed-off-by: Dietmar Maurer --- ui/src/pve/qemu/mod.rs | 81 ++++++++++++++++++++++++ ui/src/pve/{qemu.rs => qemu/overview.rs} | 28 +++----- 2 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 ui/src/pve/qemu/mod.rs rename ui/src/pve/{qemu.rs => qemu/overview.rs} (96%) diff --git a/ui/src/pve/qemu/mod.rs b/ui/src/pve/qemu/mod.rs new file mode 100644 index 0000000..448b313 --- /dev/null +++ b/ui/src/pve/qemu/mod.rs @@ -0,0 +1,81 @@ +mod overview; +use overview::QemuOverviewPanel; + +use std::rc::Rc; + +use yew::virtual_dom::{VComp, VNode}; + +use pwt::prelude::*; +use pwt::widget::{Fa, Row, TabBarItem, TabPanel}; + +use pdm_api_types::resource::PveQemuResource; + +use crate::pve::utils::render_qemu_name; + +#[derive(Clone, Debug, Properties, PartialEq)] +pub struct QemuPanel { + remote: String, + node: String, + info: PveQemuResource, + + #[prop_or(60_000)] + /// The interval for refreshing the rrd data + pub rrd_interval: u32, + + #[prop_or(10_000)] + /// The interval for refreshing the status data + pub status_interval: u32, +} + +impl QemuPanel { + pub fn new(remote: String, node: String, info: PveQemuResource) -> Self { + yew::props!(Self { remote, node, info }) + } +} + +pub struct QemuPanelComp {} + +impl yew::Component for QemuPanelComp { + type Message = (); + type Properties = QemuPanel; + + fn create(_ctx: &yew::Context) -> Self { + Self {} + } + + fn view(&self, ctx: &yew::Context) -> yew::Html { + let props = ctx.props(); + + let title: Html = Row::new() + .gap(2) + .class(pwt::css::AlignItems::Baseline) + .with_child(Fa::new("desktop")) + .with_child(tr! {"VM '{0}'", render_qemu_name(&props.info, true)}) + .into(); + + TabPanel::new() + .class(pwt::css::FlexFit) + .title(title) + .with_item_builder( + TabBarItem::new() + .key("status_view") + .label(tr!("Overview")) + .icon_class("fa fa-tachometer"), + { + let remote = props.remote.clone(); + let node = props.node.clone(); + let info = props.info.clone(); + move |_| { + QemuOverviewPanel::new(remote.clone(), node.clone(), info.clone()).into() + } + }, + ) + .into() + } +} + +impl Into for QemuPanel { + fn into(self) -> VNode { + VComp::new::(Rc::new(self), None).into() + } +} diff --git a/ui/src/pve/qemu.rs b/ui/src/pve/qemu/overview.rs similarity index 96% rename from ui/src/pve/qemu.rs rename to ui/src/pve/qemu/overview.rs index 10266f3..f9379df 100644 --- a/ui/src/pve/qemu.rs +++ b/ui/src/pve/qemu/overview.rs @@ -27,7 +27,7 @@ use crate::{ }; #[derive(Clone, Debug, Properties)] -pub struct QemuPanel { +pub struct QemuOverviewPanel { remote: String, node: String, info: PveQemuResource, @@ -41,7 +41,7 @@ pub struct QemuPanel { pub status_interval: u32, } -impl PartialEq for QemuPanel { +impl PartialEq for QemuOverviewPanel { fn eq(&self, other: &Self) -> bool { if self.remote == other.remote && self.node == other.node { // only check some fields, so we don't update when e.g. only the cpu changes @@ -53,17 +53,17 @@ impl PartialEq for QemuPanel { } } } -impl Eq for QemuPanel {} +impl Eq for QemuOverviewPanel {} -impl QemuPanel { +impl QemuOverviewPanel { pub fn new(remote: String, node: String, info: PveQemuResource) -> Self { yew::props!(Self { remote, node, info }) } } -impl Into for QemuPanel { +impl Into for QemuOverviewPanel { fn into(self) -> VNode { - VComp::new::(Rc::new(self), None).into() + VComp::new::(Rc::new(self), None).into() } } @@ -75,7 +75,7 @@ pub enum Msg { UpdateRrdTimeframe(RRDTimeframe), } -pub struct QemuPanelComp { +pub struct QemuOverviewPanelComp { status: Option, last_status_error: Option, last_rrd_error: Option, @@ -95,7 +95,7 @@ pub struct QemuPanelComp { diskwrite: Rc, } -impl QemuPanelComp { +impl QemuOverviewPanelComp { async fn reload_status(remote: &str, vmid: u32) -> Result { let status = crate::pdm_client() .pve_qemu_status(remote, None, vmid) @@ -115,10 +115,10 @@ impl QemuPanelComp { } } -impl yew::Component for QemuPanelComp { +impl yew::Component for QemuOverviewPanelComp { type Message = Msg; - type Properties = QemuPanel; + type Properties = QemuOverviewPanel; fn create(ctx: &yew::Context) -> Self { ctx.link() @@ -256,13 +256,6 @@ impl yew::Component for QemuPanelComp { fn view(&self, ctx: &yew::Context) -> yew::Html { let props = ctx.props(); - let title: Html = Row::new() - .gap(2) - .class(AlignItems::Baseline) - .with_child(Fa::new("desktop")) - .with_child(tr! {"VM '{0}'", render_qemu_name(&props.info, true)}) - .into(); - let mut status_comp = Column::new().gap(2).padding(4); let status = match &self.status { @@ -362,7 +355,6 @@ impl yew::Component for QemuPanelComp { let loading = self.status.is_none() && self.last_status_error.is_none(); Panel::new() .class(FlexFit) - .title(title) .class(ColorScheme::Neutral) .with_child( // FIXME: add some 'visible' or 'active' property to the progress -- 2.47.3 _______________________________________________ pdm-devel mailing list pdm-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel