* [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