public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pdm-devel] [PATCH datacenter-manager] ui: add download button for system report
@ 2025-12-10 13:59 Dominik Csapak
  0 siblings, 0 replies; only message in thread
From: Dominik Csapak @ 2025-12-10 13:59 UTC (permalink / raw)
  To: pdm-devel

by simply setting the 'href' of an 'a' tag to be the report as inline
data, like we do on PVE/PBS with a slight difference:

in PVE/PBS we create an 'a' tag dynamically on button click, but here we
create the a tag when we have the data and wrap a button without click
handler, so the click on the button triggers the download of the 'a'
tag.

Refactor the `get_nodename` function to another place where we can
access it from here.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 ui/Cargo.toml                        |  1 +
 ui/src/administration/node_status.rs | 45 +++++++++++++++++++++++-----
 ui/src/lib.rs                        | 16 ++++++++++
 ui/src/remotes/wizard_page_info.rs   | 16 +---------
 4 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/ui/Cargo.toml b/ui/Cargo.toml
index 1b4f0a23..9bbde7d1 100644
--- a/ui/Cargo.toml
+++ b/ui/Cargo.toml
@@ -41,6 +41,7 @@ proxmox-login = "1"
 proxmox-schema = "5"
 proxmox-subscription = { version = "1.0.1", features = ["api-types"], default-features = false }
 proxmox-rrd-api-types = "1"
+proxmox-time = "2"
 proxmox-node-status = "1"
 pbs-api-types = { version = "1.0.3", features = [ "enum-fallback" ] }
 
diff --git a/ui/src/administration/node_status.rs b/ui/src/administration/node_status.rs
index 26b6c958..a61f25a2 100644
--- a/ui/src/administration/node_status.rs
+++ b/ui/src/administration/node_status.rs
@@ -4,12 +4,16 @@ use anyhow::Error;
 use yew::virtual_dom::{VComp, VNode};
 
 use proxmox_node_status::NodePowerCommand;
-use proxmox_yew_comp::utils::copy_text_to_clipboard;
+use proxmox_time::epoch_i64;
+use proxmox_yew_comp::percent_encoding::percent_encode_component;
+use proxmox_yew_comp::utils::{copy_text_to_clipboard, render_epoch};
 use proxmox_yew_comp::{http_post, ConfirmButton, NodeStatusPanel};
 use pwt::prelude::*;
 use pwt::widget::{Button, Column, Container, Row};
 use pwt::AsyncAbortGuard;
 
+use crate::get_nodename;
+
 #[derive(Properties, Clone, PartialEq)]
 pub(crate) struct NodeStatus {}
 
@@ -74,12 +78,39 @@ impl PdmNodeStatus {
                             .with_child(&report),
                     )
                     .with_child(
-                        Row::new().padding(2).with_flex_spacer().with_child(
-                            Button::new(tr!("Copy to clipboard"))
-                                .icon_class("fa fa-clipboard")
-                                .class(pwt::css::ColorScheme::Primary)
-                                .on_activate(move |_| copy_text_to_clipboard(&report)),
-                        ),
+                        Row::new()
+                            .padding(2)
+                            .gap(1)
+                            .with_flex_spacer()
+                            .with_child(
+                                Button::new(tr!("Copy to clipboard"))
+                                    .icon_class("fa fa-clipboard")
+                                    .class(pwt::css::ColorScheme::Primary)
+                                    .on_activate({
+                                        let report = report.clone();
+                                        move |_| copy_text_to_clipboard(&report)
+                                    }),
+                            )
+                            .with_child({
+                                let button = Button::new(tr!("Download"))
+                                    .icon_class("fa fa-download")
+                                    .class(pwt::css::ColorScheme::Primary);
+
+                                let data = format!(
+                                    "data:text/plain;charset=utf-8,{}",
+                                    percent_encode_component(&report)
+                                );
+                                let timestamp = render_epoch(epoch_i64());
+
+                                let filename = match get_nodename() {
+                                    Some(nodename) => {
+                                        format!("{nodename}-pdm-report-{timestamp}.txt")
+                                    }
+                                    None => format!("pdm-report-{timestamp}.txt"),
+                                };
+
+                                html! { <a href={data} download={filename}>{button}</a> }
+                            }),
                     )
                     .into()
             })
diff --git a/ui/src/lib.rs b/ui/src/lib.rs
index 1aac7571..e693ee76 100644
--- a/ui/src/lib.rs
+++ b/ui/src/lib.rs
@@ -1,3 +1,5 @@
+use gloo_utils::format::JsValueSerdeExt;
+use gloo_utils::window;
 use js_sys::{Array, JsString, Object};
 use pdm_api_types::remote_updates::RemoteUpdateSummary;
 use pdm_api_types::remotes::RemoteType;
@@ -37,6 +39,7 @@ pub use search_provider::SearchProvider;
 
 mod dashboard;
 
+use wasm_bindgen::JsValue;
 use yew::html::IntoEventCallback;
 use yew::Html;
 use yew_router::prelude::RouterScopeExt;
@@ -303,3 +306,16 @@ pub fn extract_package_version(
 
     version.parse().ok()
 }
+
+#[derive(Deserialize)]
+struct ProxmoxServerConfig {
+    #[serde(alias = "NodeName")]
+    pub node_name: String,
+}
+
+/// Returns the nodename from the index if set
+pub fn get_nodename() -> Option<String> {
+    let value = js_sys::Reflect::get(&window(), &JsValue::from_str("Proxmox")).ok()?;
+    let config: ProxmoxServerConfig = JsValueSerdeExt::into_serde(&value).ok()?;
+    Some(config.node_name)
+}
diff --git a/ui/src/remotes/wizard_page_info.rs b/ui/src/remotes/wizard_page_info.rs
index fbe57d63..4551212e 100644
--- a/ui/src/remotes/wizard_page_info.rs
+++ b/ui/src/remotes/wizard_page_info.rs
@@ -1,10 +1,8 @@
 use std::rc::Rc;
 
 use anyhow::Error;
-use gloo_utils::{format::JsValueSerdeExt, window};
 use html::IntoEventCallback;
 use serde::{Deserialize, Serialize};
-use wasm_bindgen::JsValue;
 use yew::virtual_dom::{Key, VComp, VNode};
 
 use proxmox_schema::property_string::PropertyString;
@@ -25,7 +23,7 @@ use pdm_api_types::remotes::{NodeUrl, Remote, RemoteType, REMOTE_ID_SCHEMA};
 use pwt_macros::builder;
 
 use super::wizard_page_connect::ConnectParams;
-use crate::widget::PveRealmSelector;
+use crate::{get_nodename, widget::PveRealmSelector};
 
 #[derive(Clone, PartialEq, Properties)]
 #[builder]
@@ -414,15 +412,3 @@ impl From<WizardPageInfo> for VNode {
         VNode::from(comp)
     }
 }
-
-#[derive(Deserialize)]
-struct ProxmoxServerConfig {
-    #[serde(alias = "NodeName")]
-    pub node_name: String,
-}
-
-fn get_nodename() -> Option<String> {
-    let value = js_sys::Reflect::get(&window(), &JsValue::from_str("Proxmox")).ok()?;
-    let config: ProxmoxServerConfig = JsValueSerdeExt::into_serde(&value).ok()?;
-    Some(config.node_name)
-}
-- 
2.47.3



_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-12-10 14:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-10 13:59 [pdm-devel] [PATCH datacenter-manager] ui: add download button for system report Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal