public inbox for pdm-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pdm-devel@lists.proxmox.com
Subject: [pdm-devel] [PATCH yew-comp 1/1] form: add helpers for property strings
Date: Fri, 10 Jan 2025 11:21:37 +0100	[thread overview]
Message-ID: <20250110102142.1212874-2-d.csapak@proxmox.com> (raw)
In-Reply-To: <20250110102142.1212874-1-d.csapak@proxmox.com>

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


  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 ` Dominik Csapak [this message]
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 ` [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

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-2-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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal