From: Dominik Csapak <d.csapak@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [pdm-devel] [PATCH datacenter-manager 4/5] ui: generate URLs with the option 'web-url' property
Date: Fri, 10 Jan 2025 11:21:41 +0100 [thread overview]
Message-ID: <20250110102142.1212874-6-d.csapak@proxmox.com> (raw)
In-Reply-To: <20250110102142.1212874-1-d.csapak@proxmox.com>
This reworks `get_deep_url` so that we use the additional setting for
generating the URL. It still falls back to the previous URL generation
if either the values are not set, or no valid URL can be constructed.
Introduces a helper to extract the node from a resource.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/dashboard/top_entities.rs | 6 ++-
ui/src/lib.rs | 75 ++++++++++++++++++++------------
ui/src/pve/mod.rs | 4 +-
ui/src/pve/tree.rs | 17 ++++++--
ui/src/widget/resource_tree.rs | 21 +++++----
5 files changed, 78 insertions(+), 45 deletions(-)
diff --git a/ui/src/dashboard/top_entities.rs b/ui/src/dashboard/top_entities.rs
index 4bd71b9..af3f853 100644
--- a/ui/src/dashboard/top_entities.rs
+++ b/ui/src/dashboard/top_entities.rs
@@ -21,7 +21,7 @@ use pwt::{
use pdm_client::types::{Resource, TopEntity};
use crate::{
- get_deep_url, navigate_to,
+ get_deep_url, get_resource_node, navigate_to,
renderer::{render_resource_icon, render_resource_name},
};
@@ -131,6 +131,8 @@ impl Component for TopEntitiesComp {
let rrd = &entity.rrd_data;
let remote = &entity.remote;
+ let node = get_resource_node(resource).map(|n| n.to_string());
+
let tooltip_anchor = if let Some(info) = self.tooltip_info.as_ref() {
if info.id == resource.global_id() {
tooltip = Some(create_tooltip(remote, resource, info, &props.metrics_title));
@@ -171,7 +173,7 @@ impl Component for TopEntitiesComp {
let remote = remote.clone();
let id = resource.id();
move |_| {
- if let Some(url) = get_deep_url(&link, &remote, &id) {
+ if let Some(url) = get_deep_url(&link, &remote, node.as_deref(), &id) {
let _ = web_sys::window().unwrap().open_with_url(&url.href());
}
}
diff --git a/ui/src/lib.rs b/ui/src/lib.rs
index 5a046f6..5c6d076 100644
--- a/ui/src/lib.rs
+++ b/ui/src/lib.rs
@@ -1,4 +1,5 @@
use pdm_api_types::resource::{PveLxcResource, PveQemuResource};
+use pdm_client::types::Resource;
use serde::{Deserialize, Serialize};
mod administration;
@@ -78,38 +79,47 @@ pub(crate) fn get_remote<C: yew::Component>(
pub(crate) fn get_deep_url<C: yew::Component>(
link: &yew::html::Scope<C>,
remote: &str,
+ node: Option<&str>,
id: &str,
) -> Option<web_sys::Url> {
let remote = get_remote(link, remote)?;
- let (default_port, hash) = match remote.ty {
- pdm_api_types::remotes::RemoteType::Pve => (
- "8006",
- if id.is_empty() {
- String::new()
- } else {
- format!("v1::={id}")
- },
- ),
- pdm_api_types::remotes::RemoteType::Pbs => (
- "8007",
- if id.is_empty() {
- String::new()
- } else {
- format!("DataStore-{id}")
- },
- ),
+ let hash = match (id, remote.ty) {
+ ("", _) => String::new(),
+ (id, pdm_api_types::remotes::RemoteType::Pve) => format!("v1::={id}"),
+ (id, pdm_api_types::remotes::RemoteType::Pbs) => format!("DataStore-{id}"),
};
- let node = remote.nodes.first()?;
- let url = web_sys::Url::new(&format!("https://{}/", node.hostname));
- if let Ok(url) = url {
- if url.port() == "" {
- url.set_port(default_port);
- }
- url.set_hash(&hash);
- Some(url)
- } else {
- None
+
+ let url = match remote.web_url {
+ Some(web_url) => match (web_url.per_node_template.as_deref(), node) {
+ (Some(template), Some(node)) => {
+ web_sys::Url::new(&template.replace("{{nodename}}", node)).ok()
+ }
+ _ => web_url
+ .base_url
+ .as_ref()
+ .map(|url| web_sys::Url::new(url).ok())
+ .flatten(),
+ },
+ None => None,
}
+ .or_else(|| {
+ let node = remote.nodes.first()?;
+ let url = web_sys::Url::new(&format!("https://{}/", node.hostname));
+ url.ok().map(|url| {
+ if url.port() == "" {
+ let default_port = match remote.ty {
+ pdm_api_types::remotes::RemoteType::Pve => "8006",
+ pdm_api_types::remotes::RemoteType::Pbs => "8007",
+ };
+ url.set_port(default_port);
+ }
+ url
+ })
+ });
+ url.map(|url| {
+ url.set_hash(&hash);
+ url
+ })
}
pub(crate) fn navigate_to<C: yew::Component>(
@@ -135,3 +145,14 @@ pub(crate) fn navigate_to<C: yew::Component>(
nav.push(&yew_router::AnyRoute::new(format!("/remote-{remote}/{id}")));
}
}
+
+pub(crate) fn get_resource_node(resource: &Resource) -> Option<&str> {
+ match resource {
+ Resource::PveStorage(storage) => Some(&storage.node),
+ Resource::PveQemu(qemu) => Some(&qemu.node),
+ Resource::PveLxc(lxc) => Some(&lxc.node),
+ Resource::PveNode(node) => Some(&node.node),
+ Resource::PbsNode(_) => None,
+ Resource::PbsDatastore(_) => None,
+ }
+}
diff --git a/ui/src/pve/mod.rs b/ui/src/pve/mod.rs
index 7925bbf..763e91d 100644
--- a/ui/src/pve/mod.rs
+++ b/ui/src/pve/mod.rs
@@ -181,7 +181,9 @@ impl LoadableComponent for PveRemoteComp {
let link = ctx.link().clone();
let remote = ctx.props().remote.clone();
move |_| {
- if let Some(url) = get_deep_url(&link.yew_link(), &remote, "") {
+ if let Some(url) =
+ get_deep_url(&link.yew_link(), &remote, None, "")
+ {
let _ = window().open_with_url(&url.href());
}
}
diff --git a/ui/src/pve/tree.rs b/ui/src/pve/tree.rs
index 8b1f5ba..50a5ae4 100644
--- a/ui/src/pve/tree.rs
+++ b/ui/src/pve/tree.rs
@@ -574,7 +574,7 @@ fn columns(
DataTableColumn::new(tr!("Actions"))
.width("180px")
.render(move |entry: &PveTreeNode| {
- let (id, local_id, guest_info) = match entry {
+ let (id, local_id, guest_info, node) = match entry {
PveTreeNode::Lxc(r) => {
let guest_info = GuestInfo::new(GuestType::Lxc, r.vmid);
let local_id = guest_info.local_id();
@@ -582,6 +582,7 @@ fn columns(
r.id.as_str(),
local_id,
Some((guest_info, r.status.as_str())),
+ Some(r.node.clone()),
)
}
PveTreeNode::Qemu(r) => {
@@ -591,10 +592,16 @@ fn columns(
r.id.as_str(),
local_id,
Some((guest_info, r.status.as_str())),
+ Some(r.node.clone()),
)
}
- PveTreeNode::Root => ("root", "root".to_string(), None),
- PveTreeNode::Node(r) => (r.id.as_str(), format!("node/{}", r.node), None),
+ PveTreeNode::Root => ("root", "root".to_string(), None, None),
+ PveTreeNode::Node(r) => (
+ r.id.as_str(),
+ format!("node/{}", r.node),
+ None,
+ Some(r.node.clone()),
+ ),
};
Row::new()
@@ -642,7 +649,9 @@ fn columns(
let remote = remote.clone();
move |()| {
// there must be a remote with a connections config if were already here
- if let Some(url) = get_deep_url(link.yew_link(), &remote, &local_id) {
+ if let Some(url) =
+ get_deep_url(link.yew_link(), &remote, node.as_deref(), &local_id)
+ {
let _ = window().open_with_url(&url.href());
}
}
diff --git a/ui/src/widget/resource_tree.rs b/ui/src/widget/resource_tree.rs
index 6c4537d..1b764f7 100644
--- a/ui/src/widget/resource_tree.rs
+++ b/ui/src/widget/resource_tree.rs
@@ -23,7 +23,7 @@ use proxmox_yew_comp::{http_get, Status};
use pdm_api_types::resource::{RemoteResources, Resource};
use crate::{
- get_deep_url,
+ get_deep_url, get_resource_node,
renderer::{render_resource_name, render_status_icon},
RemoteList,
};
@@ -321,12 +321,9 @@ fn columns(
.render(|item: &PdmTreeEntry| {
match item {
PdmTreeEntry::Root => "",
- PdmTreeEntry::Resource(_, resource) => match resource {
- Resource::PveStorage(r) => &r.node,
- Resource::PveQemu(r) => &r.node,
- Resource::PveLxc(r) => &r.node,
- _ => "",
- },
+ PdmTreeEntry::Resource(_, resource) => {
+ get_resource_node(&resource).unwrap_or("")
+ }
PdmTreeEntry::Remote(_, _) => "",
}
.into()
@@ -338,13 +335,15 @@ fn columns(
.render({
let link = link.clone();
move |item: &PdmTreeEntry| {
- let (remote, id) = match item {
+ let (remote, id, node) = match item {
PdmTreeEntry::Root => return html! {},
- PdmTreeEntry::Resource(remote_id, resource) => (remote_id, resource.id()),
- PdmTreeEntry::Remote(remote_id, _) => (remote_id, String::new()),
+ PdmTreeEntry::Resource(remote_id, resource) => {
+ (remote_id, resource.id(), get_resource_node(resource))
+ }
+ PdmTreeEntry::Remote(remote_id, _) => (remote_id, String::new(), None),
};
- match get_deep_url(&link, remote, &id) {
+ match get_deep_url(&link, remote, node, &id) {
Some(url) => ActionIcon::new("fa fa-external-link")
.on_activate(move |()| {
let _ = window().unwrap().open_with_url(&url.href());
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
next prev parent reply other threads:[~2025-01-10 10:22 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH yew-comp 1/1] form: add helpers for property strings Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 1/5] server: add an optional 'web-url' property for remotes Dominik Csapak
2025-01-15 15:12 ` Thomas Lamprecht
2025-01-16 8:04 ` Dominik Csapak
2025-01-23 8:48 ` Thomas Lamprecht
2025-01-23 13:31 ` Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 2/5] ui: remote edit: add missing key for displayfield Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 3/5] ui: remote edit: rename 'Nodes' to 'Endpoints' Dominik Csapak
2025-01-10 10:21 ` Dominik Csapak [this message]
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 5/5] ui: remote edit: add 'web-url' options to the edit panel Dominik Csapak
2025-01-15 15:27 ` Thomas Lamprecht
2025-01-15 17:40 ` Dietmar Maurer
2025-01-13 14:33 ` [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
2025-01-15 13:12 ` [pdm-devel] applied: " Dietmar Maurer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250110102142.1212874-6-d.csapak@proxmox.com \
--to=d.csapak@proxmox.com \
--cc=pdm-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox