* [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable
@ 2025-01-10 10:21 Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH yew-comp 1/1] form: add helpers for property strings Dominik Csapak
` (7 more replies)
0 siblings, 8 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
instead of trying to generate it from only the endpoints, give users two
settings for generation:
* an url template where we generate an url with the nodename when we
have that information
* one general url that is used in situations where we don't have node
information
I opted for exposing both at the same time, since we always have
situation where we don't have any node information, and the placeholder
information should convey what it does if not set.
proxmox-yew-comp:
Dominik Csapak (1):
form: add helpers for property strings
src/form/mod.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
src/lib.rs | 2 ++
2 files changed, 75 insertions(+)
create mode 100644 src/form/mod.rs
proxmox-datacenter-manager:
Dominik Csapak (5):
server: add an optional 'web-url' property for remotes
ui: remote edit: add missing key for displayfield
ui: remote edit: rename 'Nodes' to 'Endpoints'
ui: generate URLs with the option 'web-url' property
ui: remote edit: add 'web-url' options to the edit panel
lib/pdm-api-types/src/remotes.rs | 23 ++++++++++
server/src/api/pve/mod.rs | 2 +
server/src/api/remotes.rs | 33 ++++++++++++++
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/remotes/edit_remote.rs | 66 ++++++++++++++++++++++++----
ui/src/widget/resource_tree.rs | 21 +++++----
9 files changed, 193 insertions(+), 54 deletions(-)
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] [PATCH yew-comp 1/1] form: add helpers for property strings
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
@ 2025-01-10 10:21 ` 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
` (6 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
when handling property strings in edit windows/input panels, we want to
have a consistent and easy way to handle them.
This introduces two helpers for parsing the property string into
separate parts (`flatten_property_string`) and one to generate the
property string again from parts (`property_string_from_parts`)
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/form/mod.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
src/lib.rs | 2 ++
2 files changed, 75 insertions(+)
create mode 100644 src/form/mod.rs
diff --git a/src/form/mod.rs b/src/form/mod.rs
new file mode 100644
index 0000000..9661c28
--- /dev/null
+++ b/src/form/mod.rs
@@ -0,0 +1,73 @@
+use serde::{de::DeserializeOwned, Serialize};
+use serde_json::{json, Value};
+
+use proxmox_schema::{ApiType, ObjectSchemaType, Schema};
+
+#[inline]
+fn format_property(name: &str, part: &str) -> String {
+ format!("_{name}_{part}")
+}
+
+/// Convert a property string to separate properties
+///
+/// This is useful for use in an [`crate::EditWindow`] when editing parts of a property string.
+/// Takes the `name` property from `data`, parses it a s property string, and sets it back to
+/// `data` as `_{name}_{key}` so this should be used as a field. If it's not desired
+/// to expose a property to the UI, simply add a hidden field to the form.
+pub fn flatten_property_string(data: &mut Value, name: &str, schema: &'static Schema) {
+ if let Some(prop_str) = data[name].as_str() {
+ if let Ok(Value::Object(map)) = schema.parse_property_string(&prop_str) {
+ for (part, v) in map {
+ data[format_property(name, &part)] = v;
+ }
+ }
+ }
+}
+
+/// Uses an [`proxmox_schema::ObjectSchema`] to generate a property string from separate properties.
+///
+/// This is useful for use in an [`crate::EditWindow`] when editing parts of a property string.
+/// Takes the single properties from `data` and adds it as a property string as `name`.
+pub fn property_string_from_parts<T: ApiType + Serialize + DeserializeOwned>(
+ data: &mut Value,
+ name: &str,
+ skip_empty_values: bool,
+) {
+ let props = match T::API_SCHEMA {
+ Schema::Object(object_schema) => object_schema.properties(),
+ _ => return, // not supported
+ };
+
+ if let Value::Object(map) = data {
+ let mut value = json!({});
+
+ let mut has_parts = false;
+ for (part, _, _) in props {
+ if let Some(v) = map.remove(&format_property(name, part)) {
+ has_parts = true;
+ let is_empty = match &v {
+ Value::String(s) => s.is_empty(),
+ _ => false,
+ };
+ if !(skip_empty_values && is_empty) {
+ value[part] = v;
+ }
+ }
+ }
+
+ if !has_parts {
+ return;
+ }
+
+ let parsed: Option<T> = serde_json::from_value(value).ok();
+
+ if let Some(parsed) = parsed {
+ match proxmox_schema::property_string::print(&parsed) {
+ Ok(prop_string) => data[name] = prop_string.into(),
+ Err(err) => log::error!("error during property string print for {name}: {err}"),
+ }
+ } else {
+ data[name] = "".into();
+ }
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index a4d68c4..091cb72 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -45,6 +45,8 @@ pub use confirm_button::{ConfirmButton, ProxmoxConfirmButton};
mod data_view_window;
pub use data_view_window::{DataViewWindow, ProxmoxDataViewWindow};
+pub mod form;
+
pub mod gauge;
pub use gauge::{Gauge, ProxmoxGauge};
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 1/5] server: add an optional 'web-url' property for remotes
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 ` Dominik Csapak
2025-01-15 15:12 ` Thomas Lamprecht
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 2/5] ui: remote edit: add missing key for displayfield Dominik Csapak
` (5 subsequent siblings)
7 siblings, 1 reply; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
this contains two optional values to generate a URL for the UI:
* per_node_template: a 'per node' template to generate an url, used for
all places where we have node information. If not set we use the
base_url as fallback to generate the url.
* base_url: An URL for reaching the remote. This is e.g. useful if there
is some reverse proxy or similar between the users browser and the
remote.
If none is set, the UI will still use the configured connections to
generate an URL.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
lib/pdm-api-types/src/remotes.rs | 23 ++++++++++++++++++++++
server/src/api/pve/mod.rs | 2 ++
server/src/api/remotes.rs | 33 ++++++++++++++++++++++++++++++++
3 files changed, 58 insertions(+)
diff --git a/lib/pdm-api-types/src/remotes.rs b/lib/pdm-api-types/src/remotes.rs
index 2a8299b..01ee95a 100644
--- a/lib/pdm-api-types/src/remotes.rs
+++ b/lib/pdm-api-types/src/remotes.rs
@@ -36,6 +36,20 @@ pub struct NodeUrl {
pub fingerprint: Option<String>,
}
+#[api]
+/// Options for the URLs used in the Web UI.
+#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
+#[serde(rename_all = "kebab-case")]
+pub struct WebUrl {
+ /// A base URL for accessing the remote.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub base_url: Option<String>,
+
+ /// A template for a per node URL. replaces {{nodename}} with the nodename.
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub per_node_template: Option<String>,
+}
+
#[api]
/// The type of a remote entry.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Deserialize, Serialize, Ord, PartialOrd)]
@@ -61,6 +75,10 @@ serde_plain::derive_fromstr_from_deserialize!(RemoteType);
description: "A cluster node IP or hostname.",
},
},
+ "web-url": {
+ type: String,
+ optional: true,
+ },
},
)]
/// The information required to connect to a remote instance.
@@ -86,6 +104,11 @@ pub struct Remote {
/// The access token's secret.
#[updater(serde(skip_serializing_if = "Option::is_none"))]
pub token: String,
+
+ /// Configuration for the Web UI URL link generation.
+ #[updater(serde(skip_serializing_if = "Option::is_none"))]
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub web_url: Option<PropertyString<WebUrl>>,
}
impl ApiSectionDataEntry for Remote {
diff --git a/server/src/api/pve/mod.rs b/server/src/api/pve/mod.rs
index 0c0ae37..dccfb72 100644
--- a/server/src/api/pve/mod.rs
+++ b/server/src/api/pve/mod.rs
@@ -1306,6 +1306,7 @@ pub async fn scan_remote_pve(
})],
authid: authid.clone(),
token,
+ web_url: None,
};
let client = connect_or_login(&remote)
@@ -1384,6 +1385,7 @@ pub async fn list_realm_remote_pve(
})],
authid: "root@pam".parse()?,
token: String::new(),
+ web_url: None,
};
let client = connection::make_pve_client(&remote)?;
diff --git a/server/src/api/remotes.rs b/server/src/api/remotes.rs
index d4412d0..e434e9b 100644
--- a/server/src/api/remotes.rs
+++ b/server/src/api/remotes.rs
@@ -3,6 +3,7 @@
use std::error::Error as _;
use anyhow::{bail, format_err, Error};
+use serde::{Deserialize, Serialize};
use proxmox_access_control::CachedUserInfo;
use proxmox_router::{
@@ -178,6 +179,15 @@ pub async fn add_remote(mut entry: Remote, create_token: Option<String>) -> Resu
Ok(())
}
+#[api()]
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+/// Deletable property name
+pub enum DeletableProperty {
+ /// Delete the web-url property.
+ WebUrl,
+}
+
// FIXME: Support `OneOf` in schema so we can use a derived Updater for all product types?
// Otherwise we need to have a custom updater struct that covers all product remotes.
#[api(
@@ -188,6 +198,14 @@ pub async fn add_remote(mut entry: Remote, create_token: Option<String>) -> Resu
flatten: true,
type: RemoteUpdater,
},
+ delete: {
+ description: "List of properties to delete.",
+ type: Array,
+ optional: true,
+ items: {
+ type: DeletableProperty,
+ }
+ },
digest: {
optional: true,
type: ConfigDigest,
@@ -202,6 +220,7 @@ pub async fn add_remote(mut entry: Remote, create_token: Option<String>) -> Resu
pub fn update_remote(
id: String,
updater: RemoteUpdater,
+ delete: Option<Vec<DeletableProperty>>,
digest: Option<ConfigDigest>,
) -> Result<(), Error> {
let (mut remotes, config_digest) = pdm_config::remotes::config()?;
@@ -211,6 +230,16 @@ pub fn update_remote(
.get_mut(&id)
.ok_or_else(|| http_err!(NOT_FOUND, "no such remote {id:?}"))?;
+ if let Some(delete) = delete {
+ for delete_prop in delete {
+ match delete_prop {
+ DeletableProperty::WebUrl => {
+ entry.web_url = None;
+ }
+ }
+ }
+ }
+
if let Some(v) = updater.nodes {
entry.nodes = v;
}
@@ -221,6 +250,10 @@ pub fn update_remote(
entry.token = v;
}
+ if updater.web_url.is_some() {
+ entry.web_url = updater.web_url;
+ }
+
pdm_config::remotes::save_config(&remotes)?;
Ok(())
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 2/5] ui: remote edit: add missing key for displayfield
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-10 10:21 ` Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 3/5] ui: remote edit: rename 'Nodes' to 'Endpoints' Dominik Csapak
` (4 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
necessary for yews dom-diff algorithm to work properly
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/remotes/edit_remote.rs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/ui/src/remotes/edit_remote.rs b/ui/src/remotes/edit_remote.rs
index ecdb7d5..61608d2 100644
--- a/ui/src/remotes/edit_remote.rs
+++ b/ui/src/remotes/edit_remote.rs
@@ -78,7 +78,10 @@ fn edit_remote_input_panel(_form_ctx: &FormContext, remote_id: &str) -> Html {
.class(FlexFit)
.padding(4)
.width("auto")
- .with_field(tr!("Remote ID"), DisplayField::new(remote_id.to_string()))
+ .with_field(
+ tr!("Remote ID"),
+ DisplayField::new(remote_id.to_string()).key("remote-id"),
+ )
.with_field(
tr!("User/Token"),
Field::new()
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 3/5] ui: remote edit: rename 'Nodes' to 'Endpoints'
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
` (2 preceding siblings ...)
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 ` Dominik Csapak
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 4/5] ui: generate URLs with the option 'web-url' property Dominik Csapak
` (3 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
as we call it in the wizard
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/remotes/edit_remote.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/remotes/edit_remote.rs b/ui/src/remotes/edit_remote.rs
index 61608d2..f9b0356 100644
--- a/ui/src/remotes/edit_remote.rs
+++ b/ui/src/remotes/edit_remote.rs
@@ -102,7 +102,7 @@ fn edit_remote_input_panel(_form_ctx: &FormContext, remote_id: &str) -> Html {
.key("nodes-title")
.padding_top(4)
.class("pwt-font-title-medium")
- .with_child(tr!("Nodes")),
+ .with_child(tr!("Endpoints")),
)
.with_custom_child(NodeUrlList::new().name("nodes").key("nodes").padding_top(2))
.into()
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 4/5] ui: generate URLs with the option 'web-url' property
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
` (3 preceding siblings ...)
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
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
` (2 subsequent siblings)
7 siblings, 0 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
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
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] [PATCH datacenter-manager 5/5] ui: remote edit: add 'web-url' options to the edit panel
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
` (4 preceding siblings ...)
2025-01-10 10:21 ` [pdm-devel] [PATCH datacenter-manager 4/5] ui: generate URLs with the option 'web-url' property Dominik Csapak
@ 2025-01-10 10:21 ` Dominik Csapak
2025-01-15 15:27 ` Thomas Lamprecht
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
7 siblings, 1 reply; 13+ messages in thread
From: Dominik Csapak @ 2025-01-10 10:21 UTC (permalink / raw)
To: pdm-devel
so users can modify it.
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
ui/src/remotes/edit_remote.rs | 59 ++++++++++++++++++++++++++++++-----
1 file changed, 52 insertions(+), 7 deletions(-)
diff --git a/ui/src/remotes/edit_remote.rs b/ui/src/remotes/edit_remote.rs
index f9b0356..27c3cb6 100644
--- a/ui/src/remotes/edit_remote.rs
+++ b/ui/src/remotes/edit_remote.rs
@@ -1,18 +1,24 @@
use std::rc::Rc;
+use anyhow::Error;
+use serde_json::Value;
use yew::html::IntoEventCallback;
use yew::virtual_dom::{VComp, VNode};
use pwt::css::FlexFit;
use pwt::prelude::*;
-use pwt::widget::form::{DisplayField, Field, FormContext, InputType};
-use pwt::widget::{Container, InputPanel};
+use pwt::widget::form::{delete_empty_values, DisplayField, Field, FormContext, InputType};
+use pwt::widget::{Container, InputPanel, Row};
+use proxmox_yew_comp::form::{flatten_property_string, property_string_from_parts};
use proxmox_yew_comp::percent_encoding::percent_encode_component;
use proxmox_yew_comp::{EditWindow, SchemaValidation};
+use proxmox_client::ApiResponseData;
use proxmox_schema::ApiType;
+use pdm_api_types::remotes::WebUrl;
+
use super::NodeUrlList;
use pwt_macros::builder;
@@ -37,6 +43,14 @@ impl EditRemote {
pub struct PdmEditRemote {}
+async fn load_remote(url: AttrValue) -> Result<ApiResponseData<Value>, Error> {
+ let mut resp: ApiResponseData<Value> = proxmox_yew_comp::http_get_full(&*url, None).await?;
+
+ flatten_property_string(&mut resp.data, "web-url", &WebUrl::API_SCHEMA);
+
+ Ok(resp)
+}
+
impl Component for PdmEditRemote {
type Message = ();
type Properties = EditRemote;
@@ -47,14 +61,15 @@ impl Component for PdmEditRemote {
fn view(&self, ctx: &Context<Self>) -> Html {
let props = ctx.props();
+ let url = format!(
+ "/remotes/{}/config",
+ percent_encode_component(&props.remote_id)
+ );
EditWindow::new(tr!("Edit") + ": " + &tr!("Remote"))
.width(800)
.min_height(400)
.on_done(props.on_done.clone())
- .loader(format!(
- "/remotes/{}/config",
- percent_encode_component(&props.remote_id)
- ))
+ .loader((load_remote, url))
.renderer({
let remote_id = props.remote_id.clone();
move |form_ctx| edit_remote_input_panel(form_ctx, &remote_id)
@@ -64,7 +79,12 @@ impl Component for PdmEditRemote {
move |form_ctx: FormContext| {
let url = url.clone();
async move {
- let data = form_ctx.get_submit_data();
+ let mut data = form_ctx.get_submit_data();
+
+ property_string_from_parts::<WebUrl>(&mut data, "web-url", true);
+
+ let data = delete_empty_values(&data, &["web-url"], true);
+
proxmox_yew_comp::http_put(&url, Some(data)).await
}
}
@@ -97,6 +117,31 @@ fn edit_remote_input_panel(_form_ctx: &FormContext, remote_id: &str) -> Html {
.input_type(InputType::Password)
.required(false),
)
+ .with_field(
+ tr!("Web Base URL"),
+ Field::new()
+ .name("_web-url_base-url")
+ .placeholder(tr!("Automatically generate from first connection.")),
+ )
+ .with_field(
+ tr!("per Node URL template"),
+ Field::new()
+ .name("_web-url_per-node-template")
+ .placeholder(tr!("Same as Web Base URL.")),
+ )
+ .with_custom_child(
+ Row::new()
+ .key("hint-text")
+ .gap(2)
+ .with_child(Container::new().with_child(tr!(
+ "Possible template values for 'per Node URL template' are:"
+ )))
+ .with_child(
+ Container::new()
+ .style("font-family", "monospace")
+ .with_child("{{nodename}}"),
+ ),
+ )
.with_custom_child(
Container::new()
.key("nodes-title")
--
2.39.5
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
` (5 preceding siblings ...)
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-13 14:33 ` Dominik Csapak
2025-01-15 13:12 ` [pdm-devel] applied: " Dietmar Maurer
7 siblings, 0 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-13 14:33 UTC (permalink / raw)
To: pdm-devel
just noticed i forgot a patch for proxmox-schema crate, so I sent it now separately
https://lore.proxmox.com/pdm-devel/20250113143159.2933689-1-d.csapak@proxmox.com/
without that patch, this series fails to compile due to the
Option<PropertyString<WebUrl>>
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* [pdm-devel] applied: [PATCH yew-comp/datacenter-manager] make ui url generation configurable
2025-01-10 10:21 [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
` (6 preceding siblings ...)
2025-01-13 14:33 ` [pdm-devel] [PATCH yew-comp/datacenter-manager] make ui url generation configurable Dominik Csapak
@ 2025-01-15 13:12 ` Dietmar Maurer
7 siblings, 0 replies; 13+ messages in thread
From: Dietmar Maurer @ 2025-01-15 13:12 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
applied
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pdm-devel] [PATCH datacenter-manager 1/5] server: add an optional 'web-url' property for remotes
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
0 siblings, 1 reply; 13+ messages in thread
From: Thomas Lamprecht @ 2025-01-15 15:12 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
Am 10.01.25 um 11:21 schrieb Dominik Csapak:
> this contains two optional values to generate a URL for the UI:
> * per_node_template: a 'per node' template to generate an url, used for
> all places where we have node information. If not set we use the
> base_url as fallback to generate the url.
>
> * base_url: An URL for reaching the remote. This is e.g. useful if there
> is some reverse proxy or similar between the users browser and the
> remote.
Why two, and not just one? And why was this already applied without
any comment/review from people in the discussion of that feature?
The unrelated fixes would be also nice as separate patches, or at
least upfront – as quite often stated already to all devs..
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pdm-devel] [PATCH datacenter-manager 5/5] ui: remote edit: add 'web-url' options to the edit panel
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
0 siblings, 1 reply; 13+ messages in thread
From: Thomas Lamprecht @ 2025-01-15 15:27 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion, Dominik Csapak
Am 10.01.25 um 11:21 schrieb Dominik Csapak:
> so users can modify it.
>
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
> ui/src/remotes/edit_remote.rs | 59 ++++++++++++++++++++++++++++++-----
> 1 file changed, 52 insertions(+), 7 deletions(-)
>
> @@ -97,6 +117,31 @@ fn edit_remote_input_panel(_form_ctx: &FormContext, remote_id: &str) -> Html {
> .input_type(InputType::Password)
> .required(false),
> )
> + .with_field(
> + tr!("Web Base URL"),
> + Field::new()
> + .name("_web-url_base-url")
> + .placeholder(tr!("Automatically generate from first connection.")),
"Generated from first endpoint."
As one might not be sure what first connection means, e.g. could be "first query
remote connection").
> + )
> + .with_field(
> + tr!("per Node URL template"),
> + Field::new()
> + .name("_web-url_per-node-template")
> + .placeholder(tr!("Same as Web Base URL.")),
> + )
This is rather confusing.. Why you went this route without adding any reasoning
at all? My take from the last discussion we had last Thursday was a single option
with potentially a UI (only) switch for UX; which I would have done with a radio
group and still a single text field to avoid letting user entering two things
where the first one will never be used if the second is entered.
In any way, _please_ lets actually review things and not just blindly apply
them...
> + .with_custom_child(
> + Row::new()
> + .key("hint-text")
> + .gap(2)
> + .with_child(Container::new().with_child(tr!(
> + "Possible template values for 'per Node URL template' are:"
> + )))
> + .with_child(
> + Container::new()
> + .style("font-family", "monospace")
> + .with_child("{{nodename}}"),
> + ),
> + )
> .with_custom_child(
> Container::new()
> .key("nodes-title")
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pdm-devel] [PATCH datacenter-manager 5/5] ui: remote edit: add 'web-url' options to the edit panel
2025-01-15 15:27 ` Thomas Lamprecht
@ 2025-01-15 17:40 ` Dietmar Maurer
0 siblings, 0 replies; 13+ messages in thread
From: Dietmar Maurer @ 2025-01-15 17:40 UTC (permalink / raw)
To: Proxmox Datacenter Manager development discussion,
Thomas Lamprecht, Dominik Csapak
> > + .with_field(
> > + tr!("Web Base URL"),
> > + Field::new()
> > + .name("_web-url_base-url")
> > + .placeholder(tr!("Automatically generate from first connection.")),
>
> "Generated from first endpoint."
already fixed this ("Use first endpoint.")
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [pdm-devel] [PATCH datacenter-manager 1/5] server: add an optional 'web-url' property for remotes
2025-01-15 15:12 ` Thomas Lamprecht
@ 2025-01-16 8:04 ` Dominik Csapak
0 siblings, 0 replies; 13+ messages in thread
From: Dominik Csapak @ 2025-01-16 8:04 UTC (permalink / raw)
To: Thomas Lamprecht, Proxmox Datacenter Manager development discussion
On 1/15/25 16:12, Thomas Lamprecht wrote:
> Am 10.01.25 um 11:21 schrieb Dominik Csapak:
>> this contains two optional values to generate a URL for the UI:
>> * per_node_template: a 'per node' template to generate an url, used for
>> all places where we have node information. If not set we use the
>> base_url as fallback to generate the url.
>>
>> * base_url: An URL for reaching the remote. This is e.g. useful if there
>> is some reverse proxy or similar between the users browser and the
>> remote.
>
> Why two, and not just one? And why was this already applied without
> any comment/review from people in the discussion of that feature?
while I started out with that, I quickly noticed that in some places/situations we don't
have *any* information about the nodes at all, so we always have to have
some general base url we can fall back to.
(i tried to convey that, but just realized that it was only in the cover letter,
should have said it in the commit message too, mea culpa)
we could still have a radio button/checkbox but we always have to have the
general url field, and simply turning on and off a single field is more
clutter than the current solution.
(I'm fine with doing either though if you find that better)
Of course, if we decide to implement more functions/features/options here that
require more/different inputs, some kind of selection for that would be
necessary.
>
> The unrelated fixes would be also nice as separate patches, or at
> least upfront – as quite often stated already to all devs..
true, but to be fair, the UI cleanups were 'upfront' of the other UI patches,
just not before the server patch, so they could have been applied either way.
_______________________________________________
pdm-devel mailing list
pdm-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pdm-devel
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-01-16 8:04 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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-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 ` [pdm-devel] [PATCH datacenter-manager 4/5] ui: generate URLs with the option 'web-url' property Dominik Csapak
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox