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
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 ` 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