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 52BAF1FF146 for ; Tue, 26 May 2026 11:31:59 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id E945418082; Tue, 26 May 2026 11:31:57 +0200 (CEST) From: Dominik Csapak To: pdm-devel@lists.proxmox.com Subject: [PATCH datacenter-manager] ui: snapshots: use constructor instead of custom `From` implementation Date: Tue, 26 May 2026 11:31:17 +0200 Message-ID: <20260526093123.1383837-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.050 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 URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [guests.rs,mod.rs] Message-ID-Hash: YQYGLQTHPDIKDYUYK5DRJUEM4OHKDF5A X-Message-ID-Hash: YQYGLQTHPDIKDYUYK5DRJUEM4OHKDF5A X-MailFrom: d.csapak@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Datacenter Manager development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: having it return a dialog when a specific property is set instead of an embedded list is better done via a custom constructor. This way we don't have to passthrough the properties of the dialog we need, we save the extra property to differentiate, and the logic is not hidden inside the `From` implementation. Signed-off-by: Dominik Csapak --- ui/src/guests.rs | 2 +- ui/src/pve/lxc/mod.rs | 1 - ui/src/pve/qemu/mod.rs | 1 - ui/src/widget/snapshot_window.rs | 42 +++++++++----------------------- 4 files changed, 13 insertions(+), 33 deletions(-) diff --git a/ui/src/guests.rs b/ui/src/guests.rs index decfffa9..c49eaff5 100644 --- a/ui/src/guests.rs +++ b/ui/src/guests.rs @@ -575,7 +575,7 @@ impl LoadableComponent for GuestPanelComp { .into(), ), ViewState::Snapshots(remote, guest_info) => Some( - SnapshotWindow::new(remote.clone(), *guest_info) + SnapshotWindow::dialog(remote.clone(), *guest_info) .on_close(ctx.link().change_view_callback(|_| None)) .into(), ), diff --git a/ui/src/pve/lxc/mod.rs b/ui/src/pve/lxc/mod.rs index a0ce86aa..4569a5ee 100644 --- a/ui/src/pve/lxc/mod.rs +++ b/ui/src/pve/lxc/mod.rs @@ -182,7 +182,6 @@ impl yew::Component for LxcPanelComp { vmid, }, ) - .embedded(true) .into() } }, diff --git a/ui/src/pve/qemu/mod.rs b/ui/src/pve/qemu/mod.rs index 1d2ffa7c..b1a5c15d 100644 --- a/ui/src/pve/qemu/mod.rs +++ b/ui/src/pve/qemu/mod.rs @@ -162,7 +162,6 @@ impl yew::Component for QemuPanelComp { vmid, }, ) - .embedded(true) .into() } }, diff --git a/ui/src/widget/snapshot_window.rs b/ui/src/widget/snapshot_window.rs index 4630759b..7e22ed79 100644 --- a/ui/src/widget/snapshot_window.rs +++ b/ui/src/widget/snapshot_window.rs @@ -11,9 +11,8 @@ use std::rc::Rc; use anyhow::{bail, Error}; use serde_json::json; -use yew::html::IntoEventCallback; use yew::virtual_dom::{Key, VComp, VNode}; -use yew::{Callback, Properties}; +use yew::Properties; use proxmox_client::ApiResponseData; use proxmox_yew_comp::{ @@ -139,16 +138,6 @@ pub struct SnapshotWindow { /// Which guest to manage snapshots for. pub guest_info: GuestInfo, - - /// Render the list inline (for embedding as a tab) instead of as a modal dialog. - #[prop_or_default] - #[builder] - pub embedded: bool, - - /// Close callback (only used in modal mode). - #[prop_or_default] - #[builder_cb(IntoEventCallback, into_event_callback, ())] - pub on_close: Option>, } impl SnapshotWindow { @@ -158,31 +147,24 @@ impl SnapshotWindow { guest_info, }) } -} -impl From for VNode { - fn from(val: SnapshotWindow) -> Self { - let embedded = val.embedded; - let on_close = val.on_close.clone(); - let title = tr!("Snapshots - {0}", val.guest_info.vmid); - - // The master renders a Column/page (toolbar + table + dialogs), not a dialog. Embedded as - // a detail-panel tab it is dropped in inline; as a standalone window it is wrapped in a - // Dialog that carries the title and the close callback. - let master: VNode = - VComp::new::>(Rc::new(val), None).into(); - if embedded { - return master; - } + /// Returns the snapshot component within a dialog + pub fn dialog(remote: impl Into, guest_info: GuestInfo) -> Dialog { + let title = tr!("Snapshots - {0}", guest_info.vmid); + let snapshot_comp = Self::new(remote, guest_info); Dialog::new(title) .min_width(720) .min_height(440) .max_height("90vh") .resizable(true) - .on_close(on_close) - .with_child(master) - .into() + .with_child(snapshot_comp) + } +} + +impl From for VNode { + fn from(val: SnapshotWindow) -> Self { + VComp::new::>(Rc::new(val), None).into() } } -- 2.47.3